I want the joystick fixed on the bottom-right the screen, no matter the resolution/window size. Although my solution works, there must be a cleaner code for this or some canvas option I don't know about.
I tried and tested a position that works on a set resolution and then factor the new resolution to that. Tested on resolutions: 434x494 and 1920x1080
For 434 pixel wide screen a joystick position.x of 434 - 115 = 319.
The factor was too big so I had to square root it for width.
For the height 120 worked for 494 height screen, I just did some hocus pocus to make it work for 1920x1080.
public Joystick joystick;
public Vector3 m_myPosition;
public RectTransform m_NewTransform;
void Start()
{
double width = Screen.width - (Mathf.Sqrt(Screen.width / 434)) * 115;
double height = 120 + (4* Mathf.Exp(Screen.width / 494));
m_myPosition.x = (float)width;
m_myPosition.y = (float)height;
m_NewTransform.position = m_myPosition;
}
I shouldn't rely on iffy code like this, any solutions?
G'day folks
Solution is everywhere on youtube...
You just change the canvas UI scale to 'Scale to screen size' and then Anchor the UI joystick object to a direction.
For my joystick I just anchored it to bottom-right and done!
In case you want in depth info on how to; I followed this tutorial: https://www.youtube.com/watch?v=w3sMD-3OJro
Related
Say I have a GameObject inside a 2D scene and a camera. And I want to change the size and position of the camera so that even when the screen resolution changes, the object will still be visible. So, how can I do that?
TL;DR: Scroll down to the bottom for the code.
First up, we must set the position of the camera to the middle of the object so the scaling of the camera would be easier.
Second, to scale the camera, we're going to change the orthographicSize of the camera in our script (Which is the Size attribute in the Camera component). But how do we calculate the attribute?
Basically, the Size attribute here is half the height of the camera. So, for example, if we set the Size to 5, that mean the height of camera going to be 10 Unity Unit (which is something I made up so you can understand easier).
So, it seems like we just have to get the height of the object, divide it by 2 and set the Size of the camera to the result, right? (1)
Well, not really. You see, while it might work on certain cases, when the width of the object is way, way longer than the screen, and the height if way, way shorter, then the camera would not able to see all of the object.
But why is that? Now, let's say that our camera has a width/height of 16/9, and our object is 100/18. That means if we scale using the height, our camera's width/height would be 32/18, and while it's enough to cover the height, it isn't enough to cover the width. So, another approach is to calculate using the width
By taking the width of the object, divide it by the width of the camera and then multiply with the height of the camera (then of course, divide by 2). We would be able to fit the whole width of the object. (Because of... ratio or something) (2)
BUT AGAIN, it has the same problem as our first approach, but the object being too tall instead too wide.
So, to solve this, we just have to place a check if the first approach (see (1)) if the object is being overflowed, and if it is, then we just use the second approach instead (see (2)). And that's it
And here's the code btw:
// replace the `cam` variable with your camera.
float w = <the_width_of_object>;
float h = <the_height_of_object>;
float x = w * 0.5f - 0.5f;
float y = h * 0.5f - 0.5f;
cam.transform.position = new Vector3(x, y, -10f);
cam.orthographicSize = ((w > h * cam.aspect) ? (float)w / (float)cam.pixelWidth * cam.pixelHeight : h) / 2;
// to add padding, just plus the result of the `orthographicSize` calculation with number, like this:
// | |
// V V
// ... cam.pixelHeight : h) / 2 + 1
Alright, I cant find any example of this already done and my attempt is yielding odd results - I need to drag to resize a flattened cube (like a plane, but must have thickness so it was a cube) using a handle in the corner. Like a window on your desktop.
So far Ive created my handle plane and gotten it via script attached to my cube plane. The cube plane and the handle are children of an empty to which the scale is being applied so that the cube plane scales from left to right as desired:
That works, however my attempt at using the delta scale handle position to scale the parent empty scales either way too much or in odd directions:
Awake() {
scaleHandle = GameObject.FindGameObjectWithTag("ScaleHandle");
scaleHandleInitialPos = scaleHandle.transform.localPosition;
}
Update()
{
width += -1*(scaleHandleInitialPos.x - scaleHandle.transform.localPosition.x);
height += -1 * (scaleHandleInitialPos.y - scaleHandle.transform.localPosition.y);
transform.parent.localScale = new Vector3(width, height, thickness);
}
what is wrong here?
Hierarchy:
Transform of the child:
With updating initialPos every Update() OR doing width = scaleHandle.transform.localPosition.x / scaleHandleInitialPos.x; where the white square is the scaleHandle
I'm writing an Android game and as I wanted it to be played in portrait mode I want the scale of the objects to remain the same in regards to the screen width. I think I managed to do that with this code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Android;
public class PowerPosition : MonoBehaviour
{
void Start()
{
float w = Screen.width;
float h = Screen.height;
Vector2 position = (Camera.main.ScreenToWorldPoint(new Vector2(w * 0.9f, w * 0.53f)));
float ratio = (w / h) / (9f / 16f);
gameObject.transform.position = new Vector3(position.x * ratio, position.y * ratio, 0);
gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x * ratio, gameObject.transform.localScale.y * ratio, gameObject.transform.localScale.z * ratio);
The issue is with the positioning. It changes and objects that should have relative distances from each other get messed up. Objects that should appear one above the other become too close and overlap.
The "position * ratio" was a test, it doesn't work well either with or without that. Here for example I had to items that I wanted to keep a consistent distance from the lower right end of the screen.
How can you fix that?
You can use percentage calculation as orientationbase to scale. That represents a relational scaleability.
There is a false friend in your mind. The displays haves different dots per inch. Will say, this value may be included your calculation.
I will try to explain it differently.
A device has a screen resolution of X-axis, Y-axis, color depth and ppi / dpi.
You can buy a display with 1920x1080xColors with 6 "or 32". With large displays you have a lower pixel density compared to small displays.
A device itself only changes X and Y if you have an orientation sensor.
Landscape 1920x1080 becomes portrait 1080x1920.
When I take an iPhone, the display has a higher pixel density than the cheaper Android devices.
In mathematics there is the famous three-sentence that is suitable for calculating proportions.
You can query the value for the pixel density from the system. You can use this value for rescaling your buttons.
I work mostly with horizontal centering. So I keep the symmetry.
I have a game like Pong, except you control both paddles and try to keep the ball in bounds. I want the paddle to always be 1/3 of the height of the screen for all resolutions. So if the Height = 900, then the paddle should be 300 high. For some reason, I can't seem to find a way that works for all resolutions anywhere. I feel I need to accomplish this through a script. Here is an image of the components for my paddle.
I need a generic formula so the paddle height is always 1/3 of the screen height.
Thanks in advanced for any help!
Get the canvas height and assign the paddle sizeDelta to have y size equal to the canvas height divided by 3.
This is the script, assumed you attach it to the paddle:
public Canvas myCanvas;
void Start() {
float canvasHeight = myCanvas.pixelRect.height;
GetComponent<RectTransform>().sizeDelta = new Vector2(GetComponent<RectTransform>().sizeDelta.x, canvasHeight/3f);
}
How can I disable the following strange resize / rescaling behaviour of a Viewport3d in WPF?
Notice that I do not change the window height:
How can I disable this "feature" of WPF (or why does it do this?)
To anyone stumbling upon this question, here's the answer by Mike Danes:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/642253a6-e7a5-4ce2-bc08-e91f2634605b/
This auto scaling is a consequence of the way perspective works.
The default field of view is 45 and the default near plane distance is
0.125. This means that a point (x, 0, 0.125) will be visible at the right side of the viewport when its x coordinate is tan(45/2) * 0.125
= 0.051776. Note how the viewport width doesn't play a part in this computation, if you make it wider the point (0.051776, 0, 0.125) will
still be visible at the right side of the viewport, that's why the
teapot appears larger.
You could compensate for a width increase by changing the field of
view and near plane distance, something along these lines:
double newWidth = grid.ActualWidth;
double originalWidth = 509.0;
double originalNearPlaneDistance = 0.125;
double originalFieldOfView = 45.0;
double scale = newWidth / originalWidth;
double fov = Math.Atan(Math.Tan(originalFieldOfView / 2.0 / 180.0 * Math.PI) * scale) * 2.0;
camera.FieldOfView = fov / Math.PI * 180.0;
camera.NearPlaneDistance = originalNearPlaneDistance * scale;
I know this is an old post, but I've come across this a few times, and I'm not sure the accepted answer is correct. Near Plane Distance defines at which point objects are too close too render. I'm not sure how this might affect the scale of the viewport3d and its children. What I have come across is that modifying Viewport3d.Width affects the scale of the 3D scene, while modifying the Height only causes clipping (or adding white space if getting larger). This is not intuitive in my opinion, but maybe its a 3D programming convention I'm not aware of.
My solution for the above problem would be to remove the Viewport3D from the Grid its in, and instead place it inside a canvas. This will prevent the window resize from changing the width of the viewport, and it should stay the same size.