- Home /
ScreenToWorldPoint giving inconsistent numbers?
Im running this snippet of code and i think it is giving me inconsistent values. I'm working with a 1920 x 1080 screen and the Vector 3 data, fullscreen.x is sometimes 8.95 and sometimes 7.25. it changes from randomly from time to time every time i build for my android phone. The variables are global so don't need to worry about that.
void Start(){
x = Screen.width;
y = Screen.height;
dist = transform.position.z - Camera.main.transform.position.z;
//if width somehow becomes smaller than height, swap
//just a fancy way of swapping w/o a temp variable
if (x < y) {
x = x ^ y;
y = x ^ y;
x = x ^ y;
}
fullScreen = Camera.main.ScreenToWorldPoint(new Vector3(x, y, dist));
}
Answer by robertbu · Nov 17, 2014 at 05:25 AM
The 'z' parameter in ScreenToWorldPoint() is the positive distance in front of the camera for the calculation. The only time this makes sense:
Camera.main.transform.position.z
...is if the camera is looking towards negative 'z' and the point you do the calculation is at 'z = 0'. It is unlikely this is how your scene is setup. If the camera has no rotation and the object with this script is at the distance you want to calculate, you can use:
float dist = transform.z - Camera.main.transform.position.z;
fullScreen = Camera.main.ScreenToWorldPoint(new Vector3(x, y, dist);
Your fancy swap seems like a waste of some cycles to me just to avoid a temporary variable.
I changed my z position to what you suggested, however I built it once fullscreen.x came out to be 7.25. I built it again, fullscreen.x came out to be 8.95. Why is it doing this? I am sure variables for the fullscreen calculation is not changing.
It doesn't just seem like a waste of time, it is :D.
Besides that why would you even use the width as height? If they are different (they usually are in most cases) and you swap them, the point will be outside of your screen.
i swap them because sometimes x becomes 1080 and y becomes 1920 ( which is not what i want). I think this is because it calculates the portrait orientation before it needs to be set to the landscape orientation
@BlasterJoker: But it is the current resolution. If you use ScreenToWorldPoint it expects a point in screen coordinates. The inverse-projection would be quite meaningless if swap them. To project a screen point to a world point it first get's converted into viewspace. Viewspace has coordinates from 0 to 1. For that it will simply divide your coordinates by Screen.width and Screen.height.
I don't get the whole point of what you want to do here? Screen.width and Screen.height are always the best source if you need the current resolution. Also why do you need them in worldspace?
I need it so I can set boundaries to stop my character from going off the screen.
I need resolution to be 1920*1080(landscape) not 1080*1920(portrait). If it uses the numbers from portrait it will give me whole new Vector3 values..
Answer by BlasterJoker · Nov 17, 2014 at 07:21 AM
The problem is that during the VERY START of the game, the orientation is always defaulted to portrait before it is detected that the resolution must be in landscape. I think i read somewhere that resolution is only changed after the first update() is called. Therefore, I delayed the code to retrieve world units by 0.5 seconds and now it is returning consistent numbers.
I've ended up with coroutine delayed by one frame. No need to wait 0.5f seconds
Answer by ShawnFeatherly · Jan 07, 2015 at 08:02 AM
I had a similiar issue. The core problem was the values in Camera.main being updated after the values in Screen.width. The fix was checking for changes in the Camera.main.aspect ratio in Update(). When that change is detected is when I did the Screen.width & Camera.main based computation.