I’m attempting to implement floating UI elements that act like target brackets over targets. It’s a bit different than the typical situation where you can simply convert world units to screen coordinates, as I need the UI elements out in front of the player (currently 4 units out). It’s to support stereoscopic 3D, including Oculus Rift. It’s not as simple as just moving the elements out into the world, since they won’t line up properly. The UI elements need to live on a point on the line between the camera’s position and the target’s position.
To handle the basic lining up of the floating UI elements, I can do this and it works perfectly:
// 1) Move UI element to the camera position
_structureGUITransform.position = gameWorldCamera.transform.position;
// 2) Face UI element toward target
_structureGUITransform.LookAt(_cachedTransform.position); // This works, but doesn't handle off-screen indicators
// 3) Move 4.0 units along the UI element's forward vector
_structureGUITransform.Translate(Vector3.forward * 4.0f);
// 4) Rotate to match camera orientation
_structureGUITransform.rotation = gameWorldCamera.transform.rotation;
So far, so good. But now I want to support icons that stop within a certain angle of the camera’s forward vector to act essentially as off-screen targets.
My thought was to replace #2 above with the equivalent of Transform.LookAt, but with the ability to constrain/clamp the X and Y rotation angles to whatever values I want relative to another vector, in this case the camera’s forward vector.
So before I worry about clamping the values, I need to get my version of Transform.LookAt working and I’m not there yet.
I replaced #2 with the below code and it almost worked:
Vector3 cross = Vector3.Cross(direction, gameWorldCamera.transform.forward);
var angleX = Mathf.Asin(cross.x) * Mathf.Rad2Deg;
var angleY = Mathf.Asin(cross.y) * Mathf.Rad2Deg;
_structureGUITransform.rotation = gameWorldCamera.transform.rotation; // Start aligned with camera
_structureGUITransform.Rotate(angleX, angleY, 0);
The Y axis rotation (left and right) appears to work correctly. But the X axis (up and down) is off by roughly 50%. It does rotate in the proper direction, just not nearly enough. I’ve tried some “magic number” stuff just for grins, like multiplying the X angle by 1.6, but that only sort of works and doesn’t really make sense anyway.
Any ideas what I’m doing wrong here? It’s possible that my angleX calculation is off and that’s the only issue, but I’m not sure where to go from here.