so with the old GUI objects in unity, if I wanted to know where a GUI object was in worldspace I could do a simple conversion of the ScreenToWorldPoint, but now if I use this same code to move an object to a UI position with the new 4.6 UI, the position it goes to is incorrect.
So how would I reference a new UI object’s position in worldspace? Like with this code snippet I could move an object to the button. How would I accomplish this same thing now?
Like, is it the position of the canvas or something else?
I’m at least using WorldToScreenPoint in my game to move screen space UI elements over gameObjects and that works perfectly. I haven’t had the need to do what you’re describing here yet.
the position that the gameObject rests at appears to be independent of the canvas, isn’t lining up with any of the ui objects or other other objects in worldspace. I thought it might be trying to line up with the canvas instead but the canvas should auto-adjust its size to fill the screen, so the center of the canvas would be what it lines up with, but it’s not lining up with that either. Too bad, I was hoping the old method of using this for gui objects would translate over to the new system =(
Are you using a CanvasScaler with Constant Pixels Size (Screen Space - Overlay)?
I am, and I think there may be a bug (as of 4.6.1):
ScreenToWorldPoint DOES work for me when using a CanvasScaler.scaleFactor of 1.
But any other scaleFactor (such as needed for retina displays) makes the reported X,Y coordinates shift in a way I can’t explain or predict. I’ve found no pattern to it, and no way to compensate.
Here’s my related question along with some example JS code that DOES work with scaleFactor = 1:
So instead I’m going to try doing it the hard way: cast rays from the corners of the screen (0,0 to Screen.width,Screen.height)–since my canvas it the same size as the screen–and then recreate the responsive layout math of the new UI system using my own code.
OK, it wasn’t THAT hard to recreate the UI positioning math… and I was able to pinpoint the bug (which I’m submitting to Unity as well):
The button I wanted to get the transform of had a custom anchor AND a position offset from that anchor (X and Y Pos values in the inspector).
The reported transform fails to multiply Pos X and Pos Y by the Canvas Scaler scaleFactor.
And you cannot compensate for this yourself because the transform reported already takes into account the custom anchors (such as X Min and Max = .6, Y Min and Max = .7) and those should not be scaled.
Here’s how I recreated a “hard coded” version of my button’s position, which accurately gives me World coordinates for the object center even when scaling for retina (assuming it has a pivot of .5,.5; if not you’ll need additional math taking that into account along with width and height):
var SF = {{ retrieve Canvas Scaler's scaleFactor here }}
var xPos : float = 45;
var yPos : float = -85;
var xAnchor : float = .6;
var yAnchor : float = .575;
var xCenter : float = Screen.width * xAnchor + xPos * SF;
var yCenter : float = Screen.height * yAnchor + yPos * SF;
transform.position = Camera.main.ScreenToWorldPoint(Vector3( xCenter, yCenter, Camera.main.nearClipPlane ));
(I could probably retrieve all those values from the object, and still avoid the transform bug. Haven’t tested yet.)