I have a responsive UI (Screen Space - Overlay) and I want to add a 3D object spinning behind a certain button. (It’s just a menu screen, luckily, so there are no concerns about collisions or lighting.)
To position that object, I need worldspace coordinates. So I want to cast a ray from the camera though the button.
What can I do, equivalent to “ScreenPointToRay” that will give me a ray from the button? (Center, corner, whatever… I can work with it!)
Thanks in advance!
You can use Transform.position and Camera.ScreenPointToRay.
Thanks! It looks like there may be a bug, though, when using that with a CanvasScaler’s Constant Pixel Size scaleFactor set to something other than 1 (as you need to do for retina displays):
EDIT: I think I have pinpointed the bug: http://forum.unity3d.com/threads/reference-new-4-6-ui-object-position-in-worldspace.267082/ (My workaround was to recreate manually the math that positions the UI button, so that I don’t have to access the new UI system at all to get the coordinates. Worked in my case, although it’s extra complexity.)
The following DOES work with scaleFactor = 1, but otherwise, the reported coordinates shift in a way I can’t explain.
Here’s what I’ve tried, in case it helps anyone. This places a 3D object behind a Unity 4.6 UI button (Screen Space - Overlay), pushes the object away from the near-plane so it’s not clipped in half, and scales the object so it remains a constant pixel size regardless of device display size (which my 2D button does naturally via Canvas Scaler, but a 3D object does not: it would appear larger on larger screens).
var button2D : GameObject;
var object3D : GameObject;
var setBack : float = 2.5; //Distance beyond camera near-plane to render object (otherwise object will clip)
var referenceScreenHeight : float = 1024; //Object already scaled to look right at this arbitrary screen size; must re-scale to compensate for other screen sizes (assuming UI Canvas uses Constant Pizel Size)
object3D.transform.position = Camera.main.ScreenToWorldPoint( Vector3( button2D.transform.position.x, button2D.transform.position.y, Camera.main.nearClipPlane + setBack ) );
object3D.transform.localScale *= referenceScreenHeight / Screen.height;