Forum Discussion
AADProductions
10 years agoExplorer
Best practice for camera rotation offset in Unity 5
I'm working on a game where you spend a lot of time looking down and it's making people a bit uncomfortable. I'd like to add a 45° offset to the camera's x rotation to take the strain off their necks the way 'AaAaaAaaa for the Awesome' did. (Unfortunately I can't rotate the world, it has to be the camera.)
This was pretty straightforward with the Oculus plugin but Unity 5's native VR has made it surprisingly tricky. :|
I've read that Unity doesn't let you change a VR camera's transform. Just for kicks I tried rotating the camera in LateUpdate, OnPreCull and in a coroutine using WaitForEndOfFrame. None worked, so that appears to be true. But I'm not clear on whether Unity has 'locked' the transform or whether Unity just wipes my changes with a later tracking update.
Parenting the camera and rotating the parent transform gets a result. But if the parent's forward doesn't match the camera's forward the horizon gets tilted as you look around. Again just for kicks I tried to fix this by copying the rotation from camera to parent each frame and then zeroing out the camera rotation, but it doesn't work. (And even if it did that seems like a great way to screw up tracking.)
Does anyone know of a best practice for this?
In a perfect world there would be a Monobehavior function that gets called after the tracking is updated, and I'd be allowed to update the camera rotation:
Or heck, while I'm wishing, something you can call on startup would be even cleaner:
This was pretty straightforward with the Oculus plugin but Unity 5's native VR has made it surprisingly tricky. :|
I've read that Unity doesn't let you change a VR camera's transform. Just for kicks I tried rotating the camera in LateUpdate, OnPreCull and in a coroutine using WaitForEndOfFrame. None worked, so that appears to be true. But I'm not clear on whether Unity has 'locked' the transform or whether Unity just wipes my changes with a later tracking update.
Parenting the camera and rotating the parent transform gets a result. But if the parent's forward doesn't match the camera's forward the horizon gets tilted as you look around. Again just for kicks I tried to fix this by copying the rotation from camera to parent each frame and then zeroing out the camera rotation, but it doesn't work. (And even if it did that seems like a great way to screw up tracking.)
Does anyone know of a best practice for this?
In a perfect world there would be a Monobehavior function that gets called after the tracking is updated, and I'd be allowed to update the camera rotation:
void OnVrTrackingUpdated () {
vrCamera.transform.Rotate (45f, 0f, 0f);//does Unity even permit this?
}
Or heck, while I'm wishing, something you can call on startup would be even cleaner:
UnityEngine.VR.InputTracking.SetLocalRotationOffset (45f, 0f, 0f);
16 Replies
Replies have been turned off for this discussion
- vrdavebOculus Staff
"AADProductions" wrote:
I'd like to add a 45° offset to the camera's x rotation to take the strain off their necks the way 'AaAaaAaaa for the Awesome' did.
To do this, make a your Camera (or OVRCameraRig) a child of an empty GameObject and pitch that GameObject down by 45 degrees."AADProductions" wrote:
Unity doesn't let you change a VR camera's transform.
Only the local transform of the Camera itself is controlled by tracking. Unity latches the Camera's initial local pose and then post-multiplies the current tracked pose onto that. The tracked pose replaces the Camera's local position and orientation each frame, just before Update() fires. But you have full control over the reference frame used by tracking if you make a parent GameObject."AADProductions" wrote:
if the parent's forward doesn't match the camera's forward the horizon gets tilted as you look around.
This is expected. When the scene first loads, I would recommend setting the world pose of the parent GameObject to whatever you want the initial camera pose to be and setting the local pose of the Camera (or OVRCameraRig) to the identity (localPosition = Vector3.zero; localRotation = Quaternion.identity; localScale = Vector3.one)."AADProductions" wrote:
In a perfect world there would be a Monobehavior function that gets called after the tracking is updated
The closest thing we have today is in the Oculus Utilities: OVRCameraRig.UpdatedAnchors (https://developer.oculus.com/doc/0.1.2.0-unity/class_o_v_r_camera_rig.html#a5ffd5318d263b81a88e04aed0c5d19d3). But I think what you need to change is the reference frame used by tracking, not the tracking-space pose itself. Using a parent GameObject will probably be the simplest way to do this even after Unity adds a special component for tracked objects."AADProductions" wrote:
Unfortunately this setup deeply confuses our Unity UI.
Here is what VR does to the Camera: http://docs.unity3d.com/Manual/VROverview.html. It shouldn't interfere much with your UI as long as it is in world space. Happy to help debug that."AADProductions" wrote:
I'm just frustrated by half a decade of getting burned every time I stray an inch from their garden path.
I know the feeling :) Hopefully we can cut down on this for you. When you run into use cases that Unity hasn't thought of yet, it's always good to file a bug report. They watch the FogBugz database and their forums pretty closely. If it's something VR-specific, be sure to let us know, too. - AADProductionsExplorer
"vrdaveb" wrote:
To do this, make a your Camera (or OVRCameraRig) a child of an empty GameObject and pitch that GameObject down by 45 degrees.
Hello - thanks for chiming in but this doesn't accomplish what I have in mind, unfortunately."vrdaveb" wrote:
"AADProductions" wrote:
if the parent's forward doesn't match the camera's forward the horizon gets tilted as you look around.
This is expected. When the scene first loads, I would recommend setting the world pose of the parent GameObject to whatever you want the initial camera pose to be and setting the local pose of the Camera (or OVRCameraRig) to the identity (localPosition = Vector3.zero; localRotation = Quaternion.identity; localScale = Vector3.one).
I think you may have the wrong idea of what I'm after. It's a hard effect to describe, but peterept's hack worked perfectly. If you try your method and his method side by side it'll give you a clear visual idea of the effect I want. Until you see the difference you could be mistaken for thinking that I'm just confused and that rotating a parent transform really will do the trick.
If you have a direct line with Unity devs I'd be super grateful if you could suggest a built-in rotation offset to them. My gut tells me other people will find it useful. - SvenVikingExpert Protege
When I rotate the parent 45 degrees on its x axis and do nothing else, the child camera's horizon gets tilted as you turn your head - the more its forward direction differs from the parent's forward direction, the worse it gets.
That sounds like it would qualify as a bug to me, but maybe I'm misunderstanding something. In, for example, a flight sim where the camera rig is parented to a plane's cockpit, if the plane angles down by 45 degrees, would the horizon remain correct as the player looks around? - AADProductionsExplorer
"Svenviking" wrote:
No I wouldn't say it's a bug. In the case of a plane cockpit things would look totally correct. In that case you're changing the local frame of reference but leaving the global frame of reference alone. Your brain gets that down is still down no matter which way your plane is rotated so if the horizon tilts it makes sense visually.
That sounds like it would qualify as a bug to me, but maybe I'm misunderstanding something. In, for example, a flight sim where the camera rig is parented to a plane's cockpit, if the plane angles down by 45 degrees, would the horizon remain correct as the player looks around?
A rotation offset like the one I'm after is closer to rotating the entire world by 45 degrees. It gives 'down' a new meaning. So if you turn your head and the horizon tilts it feels really weird.
It's one of those things that's really hard to describe/visualize but really easy to grasp once you've experienced it first hand. Give both a try in a flat environment - a basic parent rotated 45 degrees, and then peterept's camera hack. You'll see what I mean right away. - SvenVikingExpert ProtegeOK, thanks for the explanation. Interesting. Euclidean looks pretty interesting so I might just buy it and try it that way.
- AADProductionsExplorerUpdate for anyone curious, I've been experimenting more with the hack and I'm 99% sure that it introduces a one-frame lag in tracking compared to letting Unity do its thing untouched. It's subtle so you could probably get away with it in slow-moving games but you definitely notice in Euclidean when you're whipping your head around to look at something.
I'm in a holding pattern on this until either Unity exposes some kind of rotation offset in their VR settings or until OpenVR's performance in Unity improves to a point where I can use that instead of native support.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 9 years agoAnonymous
- 11 months ago
- 5 months ago
- 2 years ago