Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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:
    475
  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:
    141
    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:
    141
    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.