Search Unity

  1. Read here for Unity's latest plans on OpenXR.
    Dismiss Notice

[Solved] UnityVR execution order and Transform

Discussion in 'AR/VR (XR) Discussion' started by Kevin.Ferravanti, Jul 8, 2015.

  1. Kevin.Ferravanti

    Kevin.Ferravanti

    Joined:
    Aug 31, 2012
    Posts:
    18
    I am curious to know when in Unity's execution order does UnityVR modify the camera's transform.
    I have a simple set up, a Character Controller body, with a Camera as a child, and then another gameobject as a child of that camera.
    In a monobehaviour I have an Update() that will set a LineRenderer to start at the child's position and draw a line aligning to the child's forward direction. However, this LineRenderer doesn't show the line as you would expect, instead the line is drawn as if the head's rotation is always at euler (0, 0, 0) instead of at whatever the VR device and Camera say it should be.
    I then added an OnDrawGizmos() and had it mimic what the LineRenderer does, and it is drawn as expected.
    So I moved my original LineRenderer code from Update() to a coroutine and WaitUntilEndOfFrame() before setting the LineRenderer's points and it showed the line as expected.
    UnityVR's execution order hasn't been added to the Manual yet, but it not occurring until somewhere in the Scene Rendering execution block seems possible.

    Any information regarding UnityVR execution order or better hierarchy setup or other workarounds would be greatly appreciated.

    TL;DR - my Camera's rotation isn't set until after Update() with UnityVR, what do?
     
    Last edited: Jul 8, 2015
  2. peterept2

    peterept2

    Joined:
    Aug 1, 2012
    Posts:
    41
    Are you using the First Person Controller? The mouse code is probably reseting the camera's transform.

    You could always put your code in LateUpdate().
     
  3. Kevin.Ferravanti

    Kevin.Ferravanti

    Joined:
    Aug 31, 2012
    Posts:
    18
    Nah nothing was actually changing the camera's transform (with UnityVR being the exception), just being driven off of it. I was using the FirstPersonController but I had modified it to work with UnityVR (i.e. disabling MouseLook's rotation when a VR device is present since UnityVR needed to set rotation and not the mouse, which led to my question of when that happens since it seems to occur when the Scene renders which is after LateUpdate() but before EndOfFrame()). However, I've since upgraded to Unity 5.1.1p4 and removed FPSController to use the Oculus Utilities (beta) with their numerous scripts and I've yet to try ripping out my workarounds to see if the issue resolved itself.

    My best guess as to what was going on, based totally off what I was able to log out during the issue, was that at the beginning of the scene rendering (after Update, Late Update) the Camera's transform was being copied and the VR device's deltas where applied to the Camera, but sometime before the next loop the Camera's transform was being reset bask to its original transform that was copied. This is the only explanation I can think of since my rotation was always euler(0, 0, 0) at the beginning of the frame, but not at the end of the frame.
     
  4. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    316
    At the moment we update transforms as late as possible to minimize latency -- this means after late update and before rendering. This will be changing in a future patch to better interact with scripts and other subsystems. We will provide docs on the execution order when this change lands.

    Right now in order to get the current pose it's best to check during rendering / camera callbacks (OnPreRender, etc)
     
  5. Kevin.Ferravanti

    Kevin.Ferravanti

    Joined:
    Aug 31, 2012
    Posts:
    18
    ah okay, I'm guessing my Camera's view resetting was an issue on my side then?

    Also to your point, I can definitely hook into the OnPreRender and store those statically and drive my other components off of that, but I did recently plug into InputTracker and was about to try to drive off those values - would OnPreRender still be preferable to InputTracker? I did have to write a check to make sure VR is enabled and the Device is present since otherwise InputTracker's returned rotation is Quaternion.identity, so perhaps it would be better to just check the camera all the time instead of conditionally and have 1 frame of delayed transforms instead of having to constantly check if a device is plugged in. I guess I answered my own question for what would be easier for me, but is there a hidden cost on the engine side of things?
     
  6. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    316
    VR.InputTracking variables are updated at the same time as the camera transforms right now.. before camera render which is after late update and before rendering.

    I think OnPreCull is the best place right now if you are planning on moving objects that will render based on the camera transform / VR.InputTracking nodes. The transforms / nodes had just been updated, and you still can move things in / out of frame before they are culled. OnPreRender would actually be too late because culling already occurred.
     
  7. Kevin.Ferravanti

    Kevin.Ferravanti

    Joined:
    Aug 31, 2012
    Posts:
    18
    Even better; thank you very much for your informative replies, this has helped a lot
     
  8. made-on-jupiter

    made-on-jupiter

    Joined:
    May 19, 2013
    Posts:
    25
    Using 5.6 and this situation has not improved afaik.

    I want to render wireframes using DrawMesh on objects parented to the VR camera. Even as I'm calling DrawMesh in LateUpdate, the object's transforms are not yet updated with the latest VR camera transform, so the wireframe lags a frame.

    Calling DrawMeshNow in OnObjectRender works, except it doesn't depth-composite with the rest of the scene (the wireframes render on top of everything).

    Time to add a OnPostVr call?
     
unityunity