Forum Discussion
AADProductions
11 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
- cyberealityGrand ChampionYou just need to make the camera a child of an empty.
Look at my code here for an example of how to do it:
viewtopic.php?f=37&t=24460#p285046 - AADProductionsExplorer
"cybereality" wrote:
Hi cybereality - thanks for the script, I can tell I wasn't clear enough about what I needed guidance with. I'm already up to speed with making the camera a child of an empty and rotating/translating it in general.
You just need to make the camera a child of an empty.
Look at my code here for an example of how to do it:
viewtopic.php?f=37&t=24460#p285046
The specific problem I'm trying to solve is how to rotate the parent to match the result I'd get when doing this in the old OVRCameraRig:trackerAnchor.localRotation = tracker.orientation;
trackerAnchor.Rotate (45f, 0f, 0f);//add a constant offset to x rotation
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.
To fix this I'd normally copy the camera's rotation to the parent and zero out the camera's rotation before applying the 45 degree rotation to the parent's x axis. But since I can't zero out the camera's rotation, I'm not sure how to get the same result.
Hope I'm making sense. I'm guessing it's super simple if you're a whiz with quaternions but I'm at a loss. - cyberealityGrand ChampionYes, you are right. It messes with the horizon. Let me see what I can find out.
- petereptProtegeI think what you want is not technically supportable until Unity seperates the VRCameraTransform and the InputTracker.
The crucial thing is the ordering of quaternion rotations. You need to apply your offset after the camera orientation.
But, that said... you could *cough* hack it *cough*...
Not pretty but, parent the camera with 2 levels. First parents job is to nullify any rotations and position changes the unity is applying on the VR Camera. Grandparents job is to apply the VR.InputTracking.GetLocalRotation(VRNode.CenterEye) and add your offset.
This is working for me, and I think it achieves what you described - when I look around the horizon stays level, but I am at a 45 degree down angle. (It's a bit weird though - so it depends on your game).
To nullify the VRCam:public class NullifyTransform : MonoBehaviour {
public Transform t;
void LateUpdate () {
if (t != null)
{
transform.localRotation = Quaternion.Inverse(t.localRotation);
transform.localPosition = -t.localPosition;
}
}
}
To apply the VR orientation (could apply position as well)public class VRTransform : MonoBehaviour {
void Update () {
transform.localRotation = InputTracking.GetLocalRotation(VRNode.CenterEye) * Quaternion.Euler(45, 0, 0);
}
}
Unity package attached. - cyberealityGrand ChampionThanks for sharing, peterept. I tried for a bit yesterday, but was not able to figure it out.
- AADProductionsExplorer
"peterept" wrote:
I think what you want is not technically supportable until Unity seperates the VRCameraTransform and the InputTracker.
The crucial thing is the ordering of quaternion rotations. You need to apply your offset after the camera orientation.
But, that said... you could *cough* hack it *cough*...
I'm not above an ugly hack! :D Thanks for this, I'll give your method a try and report back. - AADProductionsExplorerGave it a shot - it works great for the camera. Nice hack.
Unfortunately this setup deeply confuses our Unity UI. I can't even fathom what it thinks is happening - our custom pointer-select is way off and the UI camera is rotating in crazy directions. I guess a hack for the hack might be possible, but I don't have the willpower to deal with yet another tangled mess of undocumented Unity nonsense.
Has Unity given an ETA on when we can expect the InputTracker to be separated from the VRCameraTransform? I'm going to take a wild guess and say they haven't. :roll:
Sorry for the bitterness! I'm just frustrated by half a decade of getting burned every time I stray an inch from their garden path. They really need to open up the source. - petereptProtegeI know how you feel! It is not easy in the "Good Old Days" of VR.
The UI raycasting is probably running before I rotate the camera in LateUpdate(), changing that to Update() and making it's priority -100 (in script priority) might fix it. (I used LateUpdate() just to be sure everything was set).
Otherwise, you may need to stick a render texture camera on the grandfather game object and use that for UI. That should definately work.
I can take a quick look if you want to send me a cut-down version of the project via PM. - petereptProtegeJust to let you know, it works ok for me with the standard Unity input system + physics raycasters.
I've attached the unity package (create a new project, import this and enable VR mode in settings).
I can't recall exactly what 'AaAaaAaaa for the Awesome' felt like - and they haven't updated to 0.7 SDK so i can't run it any more to compare. :-(
I hope you persist if you are onto something novel and fun. - AADProductionsExplorerThanks for the offer to check out the project, I'm going to pass this time but it's definitely appreciated. We've already released it and we were only hoping to tweak it a bit for comfort. (Here's a link.) That's why I'm so hesitant about digging into the UI - we put a ton of work into getting everything bug-free and changing up the UI just to rotate the vr camera isn't really justifiable.
"peterept" wrote:
I actually love the wild west feeling of VR development. Everything is new and crazy. I know my post doesn't make it seem that way but my complaint was directed more at Unity - I've just had a lot of really, really bad experiences with the engine so when I run into things like this I just feel deflated. (And yet I can't seem to stop using it so I have no one but myself to blame! :lol: )
I know how you feel! It is not easy in the "Good Old Days" of VR.
I'll give your technique another shot today and see if I can get it to behave by reordering script execution and trying different update functions.
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
- 10 years agoAnonymous
- 7 months ago
- 5 months ago