- Home /
Unity 4.6 UI: get camera ray through a button?
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!
Answer by Kiwasi · Jan 28, 2015 at 10:00 AM
...
You can use Transform.position and Camera.ScreenPointToRay.
Answer by Morgan · Jan 28, 2015 at 06:47 PM
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).
UnityScript:
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;
Your answer
Follow this Question
Related Questions
UI System not blocking Raycasts on Mobile only 2 Answers
[Solved]Cursor emulation with canvas? 0 Answers
(4.6 UI) Getting the world position of a raycast result 1 Answer
Correct use of transform.position of UI element into game screen 1 Answer
Raycast hit ignores everything except for the terrain 1 Answer