Search Unity

SteamVR loadlevel & position

Discussion in 'AR/VR (XR) Discussion' started by bdeschryver, Mar 13, 2018.

  1. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Hello guys,

    I can't find the answer to this question:
    I am using SteamVR for teleporting the player (teleport areas) (room scale setup with Vive).
    At some point, I want to do a "reset" using a script to move the player at a specific location (and ideally with some preset orientation).
    I can't do it; at the moment I am using :

    //reset
    GameObject PlayerObject = GameObject.Find("Player"); //get the SteamVR player
    PlayerObject.transform.position = start_position_for_level.transform.position; //move to start position
    PlayerObject.transform.eulerAngles = start_position_for_level.transform.eulerAngles; //set predefined angle

    but this move the "reference" of tracking to the desired position, but not the player at his current position in the tracked space !
    Sometimes when the player is close to the borders of the chaperone system/play area, after my reset script, he is moved inside a wall or object.

    How can I move the actual player/HMD to a defined position and angle ?

    THANKS !
     
  2. StickyHoneybuns

    StickyHoneybuns

    Joined:
    Jan 16, 2018
    Posts:
    207
    First use code tags so we can read your code, like this:
    Code (CSharp):
    1. GameObject PlayerObject = GameObject.Find("Player"); //get the SteamVR player
    2. PlayerObject.transform.position = start_position_for_level.transform.position; //move to start position
    3. PlayerObject.transform.eulerAngles = start_position_for_level.transform.eulerAngles; //set predefined angle
    Did you make a player prefab or use the one in SteamVR interaction system? You need to transform the entire rig. This is easily done if you are using the SteamVR prefab. If you aren't you will have to show us how you have it setup.

    Also, only use GameObject.Find as a last resort. There are much better ways to get the Player transform. If using the SteamVR plugin prefab its as simple as this:
    Code (CSharp):
    1. Using Valve.VR.InteractionSystem;
    2.  
    3. //put this at the start of your script
    4. Player player = Player.instance;//creates a reference to your player
    5. Rigidbody rb = player.GetComponent<Rigidbody>();//or you can use transform as well
    6.  
    You can also add a public GameObject and just drag your player prefab into the inspector to get the transform.
     
  3. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Hey StickyHoneyBuns,

    thank you for your answer.
    I am using the player prefab from steamVR interaction.
    I have seen that the Player position changes only when a teleport is done, but in cases of motion inside the play area, only the VRcamera moves.
    My goal is to reset the position to a predefined transform (reference), but to guarantee that the VRcamera will end up in that position. Could you explain how you would do it?
    Thanks
     
  4. StickyHoneybuns

    StickyHoneybuns

    Joined:
    Jan 16, 2018
    Posts:
    207
    Ok, I think I understand what you want. If you look at the hierarchy of the player prefab during runtime you will notice that the HMD/camera is a grandchild or child (can't remember which) of the main Player gameobject. So, I think all you have to do is move the entire player prefab through teleport or other methods then you set the position of the VR camera or it's parent if it is a grandchild. I will check when I get home if it is a child or grandchild because that will determine what needs to be set.

    But regardless of which it is you then set the position of the VR camera by using the local position which is in relation to the playspace position.

    https://docs.unity3d.com/ScriptReference/Transform-localPosition.html

    That away it will always be in a certain area of the playspace defined by you. So right after you teleport you do this while it's is still faded to black:

    Code (CSharp):
    1. Vector3 yourVector = new Vector3(X, camera.main.transform.localPosition.y, Z);//put the values of x and z as localPosition not globalPosition
    2. camera.main.transform.localPosition = yourVector;
    I kept the height the same but feel free to change it if it suits your needs.

    Also, I will have to double check this myself once I get home because it my not be completely accurate.
     
    MoritzFr likes this.
  5. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Hey,

    I managed to get it to work !
    Using elements you pointed out, the key is to combine the local position of the VR camera and the world coordinates for the entire rig.
    Here is how I did it :
    Code (CSharp):
    1. GameObject PlayerCamera = GameObject.Find("VRCamera");  //get the VRcamera object
    2. Vector3 GlobalCameraPosition = PlayerCamera.transform.position;  //get the global position of VRcamera
    3. Vector3 GlobalPlayerPosition = this.transform.position;
    4. Vector3 GlobalOffsetCameraPlayer = new Vector3(GlobalCameraPosition.x - GlobalPlayerPosition.x, 0, GlobalCameraPosition.z - GlobalPlayerPosition.z);
    5. Vector3 newRigPosition = new Vector3(welcome_start_position_object.transform.position.x - GlobalOffsetCameraPlayer.x, this.transform.position.y, welcome_start_position_object.transform.position.z - GlobalOffsetCameraPlayer.z);
    6.         this.transform.position = newRigPosition;
    Basically : Set the rig position at the reference reset position - the difference between camera and player rig.
    VR Camera is a grandchild of Player (SteamVRObject is the child between them), but to my knowldge always set to 0 position and rotation.
    It is not allowed to move the VRCamera transform, only the rig (player) can be moved.

    Thanks again !
     
    MoritzFr and StickyHoneybuns like this.