Search code examples
c#unity-game-enginevirtual-realityoculusquest

Oculus Quest - Real World Alignment


I created a 1:1 replica of my Room in 3D and unity. Now I want to align this virtual room with my real room via VR. So the Table, that I see in VR matches exactly the real one.

But since I'm using the Oculus Quest, it is recalculating its Position on every start, making it impossible to align the to worlds precisely.

However, I found a script that should allow me to recenter my VR-Headset with the Mesh of my Room. My only problem is, that I don't have a development background and the short explanations with the code snippets are not detailed enough for me.. Can somebody explain to me what to do and where to put the Code in my Scene?

Link: https://twitter.com/IRCSS/status/1231523329183559681/photo/1


Solution

  • Your question is quite broad. In general rather ask the maker of a script how it is to use ;)

    But in short for using such a script: (btw in your link in the comments you see the rest o code).

    1. Create a new script within the Assets

      ProjectView -> Right Click -> Create -> C# Script

    2. Call it accoding to the class name AlignMesh

    3. Double click to open it

    4. Past in the code.

      public class AlignMesh : MonoBehaviour
      {
          [Tooltip("Drag in the OVR rig hand used to click the buttons here")]
          public Transform HandTransform;
      
          [Tooltip("Adjust the real world distance between your two target click positions here")]
          public float ABDistance = 1.45f;
      
          public enum AligmentState
          {
              None, 
              PivotOneSet, 
              PivotTwoSet 
          }
      
          [Tooltip("If your mesh pivot does not match the real-world point A add the offset here. The mesh will be set to point A + OriginOffset")]
          public Vector3 OriginOffset;
          [Tooltip("If your mesh forward axis does not match the real-world direction A->B add the offset here. The mesh will be set to A->B * RotationOffset")]
          public Vector3 RotateOffset;
      
          public AligmentState alignmentState = AligmentState.None;
      
          private void Update()
          {
              switch (alignmentState)
              {
                  case AligmentState.None:
                      if (!OVR.Input.GetDown(OVRInput.Button.One)) return;
                      transform.position = HandTransform.position + OriginOffset;
                      alignmentState = AligmentState.PivotOneSet;
                      break;
      
                  case AligmentState.PivotOneSet:
                      if (OVRInput.GetDown(OVRInput.Button.Two))
                      {
                          alignmentState = AligmentState.None;
                          return;
                      }
      
                      if (!OVRInput.GetDown(OVRInput.Button.One)) return;
      
                      var lookAtPosition = HandTransform.position + OriginOffset;
                      var pivotOneToTwo = lookAtPosition - transform.position;
                      var scaleFactor = pivotOneToTwo.magnitude / ABDistance;
      
                      transform.LookAt(lookAtPosition, Vector3.up);
                      transfom.rotation *= RotationOffset;
                      transform.localScale *= scaleFactor;
      
                      alignmentState = AligmentState.PivotTwoSet;
                      break;
      
                  case AligmentState.PivotTwoSet:
                      if (OVRInput.GetDown(OVRInput.Button.Two))
                      {
                          alignmentState = AligmentState.None;
                      }
                      break;
              }
          }
      }
      
    5. In your scene's Hierarchy select your root mesh object of the world/room you want to align

    6. In the Inspector click Add Component and search for your created AlignMesh

    7. Into the leftHandPosition drag and drop the according hand from the OVR rig. And in ABDistance adjust the real-world distance between your two click positions in meters.


    A little explanation what this does:

    • The first click sets the room to that position

      So make sure that your real-world point A matches with the pivot point of the object in Unity!

    • The second click is used to set its rotation (so it's forward axis points to B) and scale.

      So make sure that your real-world point B is aligned to A thus that this direction matches with your meshes FORWARD axis

    How does it work on a code basis:

    • None

      Initially you are in an IDLE state None where your script only waits for the click on Button.One.

      Once you press the button the room is set to according position and you go to PivotOneSet

    • PivotOneSet

      Now you are waiting for either a Button Two press => Cancel => back to None state

      Or your press Button One again to set the second position B

      Once this second position is set you adjust the rooms orientation and scale to match with the real world coordinates. Then you go to PivotTwoSet state.

    • PivotTwoSet

      This does basically nothing but waiting for a Button Two click in order to reinitialize the setup process by going back to None state.