Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

VR [fixed] Wanted: Rift camera reset function

Discussion in '5.1 Beta' started by Todd-Wasson, Apr 21, 2015.

  1. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    EDIT: As of beta 6, UnityEngine.VR.InputTracking.Recenter() can be used per Ed unity's post instead of the longer, temporary solution posted in this thread. Just tested and confirmed working.

    Is there any talk at Unity about adding a reset function for the camera in VR mode at some point? A couple of iterations ago there was one stuffed in a VR class somewhere that looked like an Oculus function, but it went away at some point and I don't see anything like that in the new implementation.

    With the new system it probably wouldn't be too hard to add something myself by putting in an extra object and adjusting the root object I have above the camera in the hierarchy according to the difference between that and the real camera position at the time my reset function is called, then just move my camera parent object by that amount to shift it. I'll try that for now, but doing this would be adding an extra object for every camera (three instead of just one without the Rift) so it'd be nice not to have to.
     
    Last edited: May 13, 2015
    gdebojyoti and darky like this.
  2. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    EDIT 2: Changed the ResetRootPosition function to use world coords instead of local coords. This seems to work well enough although it's only resetting the position and not the orientation. In my case this is good enough for now so adding orientation reset is left as an exercise for the reader.

    Ok, here's the first shot at a solution I've come up with in the meantime that seems to work reasonably well. I haven't tried this with multiple cameras yet (next on the todo list) but think it will probably be ok there.

    This all works under the assumption that you have only one active camera object in a scene at a time (water reflection cams and so forth not included, those can be left alone to operate normally). In my system I use SetActive() to turn all game objects with the cameras on and off, only one is active at a time. If you're not doing that then this will not work, you'll have to modify it.

    There are three scripts below. Here's what to do and how it works:

    The InputManager script is placed on an empty object in the scene somewhere that processes the C key for resetting the camera. It doesn't matter if this object is at the root level or not. It will find all the relevant objects at Start() (whether they're active or not) and create references to them. So either create an object and put this script on it, or just add the code in this InputManager to Start() and Update() to wherever you're processing keystrokes.

    For each object with a camera in the scene that will use VR, create two objects above it in the hierarchy. From top level down it goes like this:

    {name} Camera Reset Position -> {name} Camera Root -> {name} Camera game object (whatever has the actual camera component in it).

    After adding the two extra objects (or one if you already have your own root object to control movement), be sure to zero out the positions of Camera Root and Main Camera in the inspector.

    Camera Reset Position object:
    When moving the camera along with a car or character or whatever, move it at the top level by changing the {name} Camera Reset Position object's transform. If you have some camera controller that does that already, it may be enough to move the controller script from your camera object to the top level Camera Reset Position object.

    ---Each Camera Reset Position object gets the CameraResetPosition script attached to it.


    Camera Root object:
    Under the Camera Reset Position object is the Camera Root object. This is what gets moved relative to Camera Reset Position when you press the "C" key. The Main Camera which is controlled by the head tracking stuff just moves along with it as its child. The idea is for the Camera Root to get moved in such a way that the actual camera moves to the Camera Reset Position when you press "C." The camera just comes along with the Camera Root for the ride and is then free to move normally with the headtracking.

    ---Each Camera Root object gets the CameraRoot script attached to it.


    How it works:

    Input Manager's Start() function calls Resources.FindObjectsOfTypeAll<CameraResetPosition>() to find all objects in the scene, active or not, that have a CameraResetPosition script attached. Then, during update it checks for a "C" keypress. If one occurs, it runs through all the objects that have a CameraResetPosition script on them and calls ResetCameraPosition() in the CameraResetPosition script on that object. It does this only for the currently active camera (you only have one, right? :) )

    When ResetCameraPosition is called, our execution has jumped from InputManager to that top level object (Camera Reset Position). That has a reference to its child (its Camera Root). It calls CameraRoot.ResetRootPosition() on that child.

    Now the execution is in the CameraRoot. This just computes the difference in position between the reset position and the actual camera object and moves the Camera Root by that amount, thereby (hopefully) moving the real camera to the actual reset position.

    There are times when it doesn't work correctly. Sometimes in Unity when clicking the Camera object in the hierarchy, Unity shows a matrix error which in my testing would usually turn the local y coordinate to 0, so the resetting would not work correctly anymore. This is part of the reason I'm using world coords instead of local coords. Hopefully they'll fix that, but in the meantime as long as you don't go fiddling around in the hierarchy too much and don't try to examine that camera directly, it seems to work well enough for government work.

    Here are the scripts:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class InputManager : MonoBehaviour {
    6.     CameraResetPosition[] cameraResetPosition;
    7.     // Use this for initialization
    8.     void Start()
    9.     {
    10.         cameraResetPosition = Resources.FindObjectsOfTypeAll<CameraResetPosition>();
    11.  
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.        if(Input.GetKeyDown(KeyCode.C))
    18.         {
    19.             //reset all objects that have a CameraResetPosition on them but only if they're active
    20.  
    21.             for (int i = 0; i < cameraResetPosition.Length; i++)
    22.             {
    23.                 if (cameraResetPosition[i].gameObject.activeSelf)
    24.                 {
    25.                     cameraResetPosition[i].ResetCameraPosition();
    26.                 }
    27.             }
    28.         }
    29.     }
    30. }
    31.  
    32.  
    Code (csharp):
    1.  
    2. public class CameraResetPosition : MonoBehaviour {
    3.  
    4.     CameraRoot cameraRoot;
    5.  
    6.     void Start()
    7.     {
    8.         cameraRoot = GetComponentInChildren<CameraRoot>();
    9.     }
    10.  
    11.     public void ResetCameraPosition()
    12.     {
    13.         cameraRoot.ResetRootPosition(transform);
    14.     }
    15. }
    16.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CameraRoot : MonoBehaviour {
    6.     Camera cameraChildObject;
    7.  
    8.     void Start()
    9.     {
    10.         //print(name + " Start");
    11.         cameraChildObject = GetComponentInChildren<Camera>();
    12.         //print("cameraChildObject " + cameraChildObject.name);
    13.     }
    14.  
    15.     public void ResetRootPosition(Transform resetPositionTransform)
    16.     {
    17.         Vector3 difference = resetPositionTransform.position - cameraChildObject.gameObject.transform.position;
    18.         transform.position += difference;
    19.     }
    20. }
    21.  
    If anybody's come up with a smarter, easier way, I'm all ears. Hopefully Unity will make a function that does this instead so the extra Camera Reset Position object can be skipped and we don't have the extra complexity. In the meantime this might be a good enough crutch or starting point.
     
    Last edited: Apr 23, 2015
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    6,313
    It used to be this..

    Code (csharp):
    1.  
    2. OVRDevice.ResetOrientation();
    3.  
    Then it changed to this..
    Code (csharp):
    1.  
    2. OVRManager.display.RecenterPose();
    3.  
    Does this not work anymore?
     
    astracat111 likes this.
  4. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    No, there's no OVRManager class anymore. It's been replaced by something that doesn't appear to have a function for this yet. Hopefully soon, my way didn't work very well in a lot of situations as it turns out. :rolleyes:
     
  5. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    I suppose you could import the OVRManager class from the Unity 4 implementation, I guess. I haven't tried it and don't know if it would work.
     
  6. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    6,313
    Well, I guess that makes sense if Unity's VR module is supposed to be a generic front end... Except that it breaks everything and requires a reworking of all of your old OVR code..

    All I could find on the API was this.
    https://docs.google.com/document/d/1GkSkKsjyl5NOvShN-jG_nmuTav6ckRWlJUt6LnO5b5o/edit

    And I don't see any reset function, or anything about transform inputs at all, really. Downloading 5.1 now.. Will tinker around with it later..

    I would not import the old OVR stuff, thats going to get really weird really quick.
     
  7. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    I just tried grabbing the OVRManager script, but it doesn't work because there's a "using Ovr" in there. I might be mistaken, but it looks like you'd need the whole OVR package installed which is not compatible with the new beta because of the new cams. Hopefully they'll add something soon.

    I'm having so many problems with VR on this new beta that I'm not really sure if I'm going to keep this or just roll it back until the next update. I do like how the new system works a lot more than the old way and it does render noticeably faster, but we seem to have lost the ability to record video and there are all kinds of rendering problems in the Rift itself now. Fraps just crashes the program and there's not a dual rendering anymore on the window that's duplicated to the desktop, so at this point I don't see a way of making YouTube videos that run on the Rift, something that's important for promotion.

    The rendering is flickering or totally missing in one eye a lot of the time, or sometimes only one object against the clear color background is there, stuff like that. I even had it at one point where each eye was rendering from a different camera in the scene part of the time. So it's pretty flaky at the moment even though the frame rate is a lot higher which is what I've been hoping for. I've submitted a few bug reports. This is just the first release on the new system so I don't expect perfection, but I kind of wish they'd have waited a little longer and ironed out some of this stuff a little more before putting it out here.

    Oh well, at least performancewise it's a big improvement so I know what I can get away with when they iron out some of these glitches. I'm very happy with that part!
     
  8. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Yes, you're right, you definitely don't want to import the old OVR package. Some of the problems I was reporting in my threads were caused by that. It didn't help that I didn't RTFM very well when first doing this which clearly says to update the Oculus stuff to the latest 5.x beta version. Duh.... :rolleyes:
     
  9. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    What I'd really like is some kind of very rough, ballpark estimate from Unity on when some of this stuff might get fixed or when the next update might come. Of course you can't predict how long problems like these take to solve, but if the next beta isn't going to come for several weeks at least, I might just roll back and throw away the work I've done the last few days. There's a lot of really great stuff here but the glitches at the moment are making it a little tough to work with for me.
     
  10. MS80

    MS80

    Joined:
    Mar 7, 2014
    Posts:
    333
    1+
    reset-function is fundamental!

    Till now some missing functionality is the only downside of a generic vr module. Apart from that I am very satisfied with the new vr integration!

    Besides they are working on this:
    • HRTF audio
    • UGUI input method based on head direction
    • Ability to use GL calls per eye
    • Expose VR settings in editor window (like Audio settings, etc)
    • Gear VR support
    • Linux support
    • Share more work between the stereo eye rendering
     
    Last edited: Apr 22, 2015
  11. MS80

    MS80

    Joined:
    Mar 7, 2014
    Posts:
    333
    I have a second output on the monitor, too! It is a streched, normal render without distortion effects.

    Did you try it with a new project, there should be not flickering. Maybe it is the health warning, you could deactivate it =>
     
  12. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Thanks for the video. I'll watch it and try to disable the warning.

    The flickering I'm talking about doesn't have anything to do with the warning flickering which is documented as a known issue. The stuff I'm talking about is after the warning is gone. At one point I had one eye not flickering at all, but it was showing nothing but the steering wheel.

    In another case I did a new project with water and a tree in it. The first time I ran it it was fine, then each time I ran it after that something different would happen. If I turned away from the tree so it wasn't in the view frustrum anymore things were normally fine, but if I'd roll my head slightly the sky would turn to the blue background color. Look at the tree and the tree would not render at all in the right eye but would be visible in the water reflection. Run it again and it would be visible but flicker a lot in one eye, that kind of thing. My scenes are almost always flickering or doing something wierd.

    As for the duplicate view, I meant something like this isn't currently available with the new system:



    To me this is important to have for promotional purposes. My Rift videos seem to get a lot more views than the non-Rift ones and ought to be good for generating some sales among Rift users. I had tried recording straight off the Rift with Fraps but it immediately crashes my built program.

    Just to be clear, the rendering in the preview window or duplicate is always fine unless it's in full screen without the Rift where everything appears a lot darker than normal. The flickering is only happening in the Rift itself. Part of the reason I wanted to record a video was to show what it was doing, but I haven't figured out a way to do it yet.

    Anyway, hopefully they'll iron out this stuff before too long. I just hope it's not a month or two from now, otherwise I really need to just roll back to the earlier beta.
     
    Last edited: Apr 23, 2015
  13. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    Another vote for resetting headtracking. There's a simple workaround, but it really should be there.
    Also agree on the need for displaying stereo images outside the rift, we used to do this quite often for live demos.

    In spite of all that, the new VR integration feels really slick compared to the old OVR plugin, as well as being much more stable.
     
  14. JonDadley

    JonDadley

    Joined:
    Sep 2, 2013
    Posts:
    137
    Another vote for a 'recenter headtracking' function! We really do need this.

    As others have said, I've been very impressed with the quality of the VR integration so far. A few more additions and improvements and it will be ideal :)
     
  15. Ed-unity

    Ed-unity

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    279
    Resetting the Head Tracking position is currently planned to be added to the integration. For now, you'll need to do something similar to what Todd has done in order to Reset.
     
  16. MS80

    MS80

    Joined:
    Mar 7, 2014
    Posts:
    333
    Cool! Will it be in 5.1 beta5?
     
  17. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Thanks, Ed. Looking forward to it.

    Others: I've updated the code in the thread here to use world position instead. Seems to work a lot better and should be suitable in the meantime. It's not too tough to use, you just add one more parent object to the top of the camera object chain, drop two scripts on there, and move your camera motion script to the top level. It only updates the position on reset, not the orientation (that's all I need so I didn't go further than that). Orientation shouldn't be too hard to add though, just another copy.
     
  18. MS80

    MS80

    Joined:
    Mar 7, 2014
    Posts:
    333
    Thanks Todd! In the meantime, this is a pretty good solution!
     
  19. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Thanks. It doesn't work right with beta 4 though. It seemed reasonably ok in beta 3 at least. Fingers crossed for beta 5. :)
     
  20. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    269
    This will be part of beta 6.

    VR.InputTracking.Recenter()
     
    idunlop_oefun, MS80 and SAOTA like this.
  21. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Great to hear. Thanks for letting us know. :)
     
  22. korinVR

    korinVR

    Joined:
    Jul 7, 2012
    Posts:
    8
    Does the VR.InputTracking.Recenter() work?
    Unity 5.1.0 beta 6 says "error CS0103: The name `VR' does not exist in the current context."
     
  23. Ed-unity

    Ed-unity

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    279
    Try UnityEngine.VR.InputTracking.Recenter()
     
  24. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,061
    Works like a charm, Ed. Thanks.
     
  25. korinVR

    korinVR

    Joined:
    Jul 7, 2012
    Posts:
    8
    RayOfMinneapolis likes this.