Search Unity

Steam VR Plugin : Reset Position and orientation

Discussion in 'AR/VR (XR) Discussion' started by VirtualisDev, Mar 3, 2016.

  1. VirtualisDev

    VirtualisDev

    Joined:
    Jul 21, 2015
    Posts:
    30
    Hello,

    I'm currently working with Steam VR Plugin for Unity and i'm converting my whole project for the fantastic HTC Vive Pre and forward.

    UNFORTUNATELY i didn't figured out the equivalent to :
    " UnityEngine.VR.InputTracking.Recenter(); "

    I tried SteamVR.instance.hmd.ResetSeatedZeroPose(); without any success...
    Seems on the web i'm not alone but didn't found any answer.

    Does anyone can help ?
     
  2. Deleted User

    Deleted User

    Guest

    This problem may be Unity5.3.3 Bug
     
  3. Psyco92

    Psyco92

    Joined:
    Nov 15, 2013
    Posts:
    22
    Code (CSharp):
    1.     public KeyCode reOrient;
    2.  
    3.     void Update()
    4.     {
    5.         if (Input.GetKeyDown(reOrient) == true)
    6.         {
    7.             Valve.VR.OpenVR.System.ResetSeatedZeroPose();
    8.  
    9.             //transform.parent.localEulerAngles -= transform.localEulerAngles + transform.parent.localEulerAngles;
    10.         }
    11.         //transform.parent.localPosition = -transform.localPosition;
    12.     }
    Valves reset seems like the way to go, but it does nothing I can detect. Use the commented lines and remove/comment the ResetSeatedZeroPose line, make sure the camera (origin) is a child of something that looks at your centre. And dont forget to set a reOrient key in the inspector (This code can create strange offsets when reorienting)
     
    Last edited: Jun 1, 2016
    NeoTokyo_Nori likes this.
  4. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
  5. gstarch

    gstarch

    Joined:
    Mar 21, 2015
    Posts:
    4
    I spent a lot of time looking for a answer on this. Tried all of the options on this thread and the miracle one without success. Looked like several of the SteamVR/Valve and native solutions stopped working after a recent update. Eventually wrote this script which took care of it to my liking.

    This script will allow a reset of the SteamVR camera rig to align with a transform representing the desired head position in the scene. Attach to any GameObject in the scene. Useful for seated experiences like cockpits.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ResetSeatedPosition : MonoBehaviour {
    4.     [Tooltip("Desired head position of player when seated")]
    5.     public Transform desiredHeadPosition;
    6.     private Transform steamCamera;
    7.     private Transform steamController;
    8.  
    9.     // Update is called once per frame
    10.     void Update () {
    11.  
    12.         if (Input.GetKeyDown(KeyCode.Space))
    13.         {
    14.             if (desiredHeadPosition != null)
    15.             {
    16.                 ResetSeatedPos(desiredHeadPosition);
    17.             }
    18.             else
    19.             {
    20.                 Debug.Log("Target Transform required. Assign in inspector.");
    21.             }
    22.        
    23.         }
    24.     }
    25.  
    26.     private void ResetSeatedPos(Transform desiredHeadPos){
    27.  
    28.         //find VR Camera and CameraRig transforms in scene
    29.         steamCamera = FindObjectOfType<SteamVR_Camera>().gameObject.transform;  
    30.         steamController = FindObjectOfType<SteamVR_ControllerManager>().transform;
    31.  
    32.         if ((steamCamera != null) && (steamController != null))
    33.             {
    34.             //{first rotation}
    35.                 //get current head heading in scene
    36.                 //(y-only, to avoid tilting the floor)
    37.                 float offsetAngle = steamCamera.rotation.eulerAngles.y;
    38.                 //now rotate CameraRig in opposite direction to compensate
    39.                 steamController.Rotate(0f, -offsetAngle, 0f);
    40.  
    41.             //{now position}
    42.                 //calculate postional offset between CameraRig and Camera
    43.                 Vector3 offsetPos = steamCamera.position - steamController.position;
    44.                 //reposition CameraRig to desired position minus offset
    45.                 steamController.position = (desiredHeadPos.position - offsetPos);
    46.  
    47.                 Debug.Log("Seat recentered!");
    48.             }
    49.         else
    50.             {
    51.                 Debug.Log("Error: SteamVR objects not found!");
    52.             }
    53.     }
    54. }
    55.  
    Turned out to be simpler than I expected. Hope it can save someone else the time!

    Cheers,

    Gerry

    PS: Running Unity 2017.2
     
  6. Paalo

    Paalo

    Joined:
    Jan 20, 2016
    Posts:
    8
    The solution @gstarch suggested is the way to go. It works both for Room Scale & Seated Experiences.

    Some things to remember though:
    • An important change is that the
      SteamVR_ControllerManager
      -script isn't attached to the
      [CameraRig]
      -prefab coming with the SteamVR-plugin anymore (in SteamVR version 1.2.3 and up).
      • This also means that the variable
        steamController
        is supposed to be set to the
        [CameraRig]
        -prefab coming with the SteamVR-plugin.
    • How Unity.XR works:
      • The function
        UnityEngine.XR.InputTracking.Recenter();
        ONLY works for Seated/Standing Experiences, ie. it won't do anything if you have set up a Room Scale-experience.
    Here's our modified version of @gstarch's solution. Works with
    Unity 2018.3.0b11
    &
    SteamVR Version 1.2.3


    Hope this helps someone!

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class PlayAreaController : MonoBehaviour
    4. {
    5.     [Tooltip("Desired head position of player when seated")]
    6.     public Transform desiredHeadPosition;
    7.  
    8.     //Assign these variables in the inspector, or find them some other way (eg. in Start() )
    9.     public Transform steamCamera;
    10.     public Transform cameraRig;
    11.  
    12.     private void Update()
    13.     {
    14.         if (Input.GetKeyDown(KeyCode.Space))
    15.         {
    16.             if (desiredHeadPosition != null)
    17.             {
    18.                 ResetSeatedPos(desiredHeadPosition);
    19.             }
    20.             else
    21.             {
    22.                 Debug.LogError("Target Transform required. Assign in inspector.", gameObject);
    23.             }
    24.         }
    25.     }
    26.  
    27.     private void ResetSeatedPos(Transform desiredHeadPos)
    28.     {
    29.         if ((steamCamera != null) && (cameraRig != null))
    30.         {
    31.             //ROTATION
    32.             // Get current head heading in scene (y-only, to avoid tilting the floor)
    33.             float offsetAngle = steamCamera.rotation.eulerAngles.y;
    34.             // Now rotate CameraRig in opposite direction to compensate
    35.             cameraRig.Rotate(0f, -offsetAngle, 0f);
    36.  
    37.             //POSITION
    38.             // Calculate postional offset between CameraRig and Camera
    39.             Vector3 offsetPos = steamCamera.position - cameraRig.position;
    40.             // Reposition CameraRig to desired position minus offset
    41.             cameraRig.position = (desiredHeadPos.position - offsetPos);
    42.  
    43.             Debug.Log("Seat recentered!");
    44.         }
    45.         else
    46.         {
    47.             Debug.Log("Error: SteamVR objects not found!");
    48.         }
    49.     }
    50. }
     
    Last edited: Dec 5, 2018
  7. Boemak

    Boemak

    Joined:
    May 29, 2013
    Posts:
    48
    This is just what I needed. Thanks.
     
    Paalo likes this.
  8. bugaboostudio

    bugaboostudio

    Joined:
    Sep 30, 2016
    Posts:
    3
    It worked lika a charm!
     
    Paalo likes this.
  9. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    I'm not sure what you are setting as the "Camera Rig"
    I can make an object to be the "desiredHeadPosition" and I see the Players "VRCamera" to set as the "steamCamera"
    but whats the rig? Is this something that has been removed in SteamVR 2.x (SDK 1.7.15) ?
     
  10. tgaldi

    tgaldi

    Joined:
    Oct 28, 2015
    Posts:
    102
    To reset orientation I use the following:

    Code (CSharp):
    1.  
    2.         public void ResetTracker()
    3.         {
    4.             StartCoroutine( Boresight() );
    5.         }
    6.  
    7.         private IEnumerator Boresight()
    8.         {
    9.             activeCameraRig.transform.rotation = Quaternion.identity;
    10.             yield return null;
    11.  
    12.             InputTracking.Recenter();
    13.             yield return null;
    14.  
    15.             List<XRNodeState> states = new List<XRNodeState>();
    16.             InputTracking.GetNodeStates( states );
    17.             var head = states.Find( s => s.nodeType == XRNode.Head );
    18.             if( head.TryGetRotation( out Quaternion orientation ) )
    19.                 activeCameraRig.transform.rotation = Quaternion.Inverse( orientation );
    20.         }
    21.  
    activeCameraRig is the top level transform on your VR rig.


    Code (CSharp):
    1.         private void Start()
    2.         {
    3.             switch( XRSettings.loadedDeviceName )
    4.             {
    5.                 case "Oculus":
    6.                     activeCameraRig = Instantiate( OculusCameraRig );
    7.                     break;
    8.  
    9.                 case "OpenVR":
    10.                     activeCameraRig = Instantiate( ViveCameraRig );
    11.                     break;
    12.  
    13.                 default:
    14.                     break;
    15.             }
    16.             onCameraRigActive.Invoke( activeCameraRig );
    17.         }
    18.  
     
    Ortho3Dox likes this.
  11. Giantbean

    Giantbean

    Joined:
    Dec 13, 2012
    Posts:
    144
    Thank you. That image helped clarify things as did the code. Unfortunately when I load from one scene to another the player is still facing the wrong direction in the new scene.

    Edit: Silly me. I Just needed to turn the player prefab around.

    P.P.S Edit … Turning the player prefab only works for going to the scene if I return to the previous scene The player will now be facing the wrong way in that scene. :(
     
    Last edited: Nov 7, 2019
  12. algorithmicvertex

    algorithmicvertex

    Joined:
    May 22, 2016
    Posts:
    8
  13. djlins

    djlins

    Joined:
    Jun 15, 2013
    Posts:
    23
    Hi fgheorghe.
    Thank you for posting that 2020 version.
    I have given it a go but it resets the Y value as well and puts the floor up to eye level. I have to close and restart SteamVR every time to put the floor back at my feet again.
    Would you have any experience on what to do to keep the Y setting?
    Cheers,
    Lins
     
  14. algorithmicvertex

    algorithmicvertex

    Joined:
    May 22, 2016
    Posts:
    8
    Hi Lins, I am wondering if the Y setting changes due to player height settings in SteamVR, outside unity, or depending on your setup, if the camera needs to be a made a child of an empty object set at a desired height - this way if Y is reset to 0, and the camera’s parent is set to 1, then when the position gets reset it will be above the floor at Y 1. Hope this helps!
     
  15. djlins

    djlins

    Joined:
    Jun 15, 2013
    Posts:
    23
    I think it was a mismatch of the SteamVR_Settings saying tracking space origin seated. When I set that to standing and then in the code set
    ETrackingUniverseOrigin.TrackingUniverseSeated
    to
    ETrackingUniverseOrigin.TrackingUniverseStanding
    then it keeps the floor at my feet. Even if I have set my room guardian to stationary or free draw etc. It always sets up as standing for SteamVR.
     
    algorithmicvertex likes this.