2

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

derHugo
  • 83,094
  • 9
  • 75
  • 115
foliran
  • 75
  • 6

2 Answers2

2

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.

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Thank you very much! I only have one Question left: When I make sure that my real-world point A matches with the pivot point of the object in Unity, he is no more in the Center of my Mesh (I used the Plugin SuperPivot) So now the first click perfectly works, but the second for the rotation, rotates wrong 90° around the pivot - why? – foliran Jun 19 '20 at 13:32
  • The author of the script assumes that alo the rotation of your model matches ... what happens sis that it rotates in a way that the rooms **FORWARD** axis points towards `B`! If your object is rotated by 90° then probably the mashes forward axis doesn't match correctly – derHugo Jun 19 '20 at 14:17
0

This trick will works for a simple ride in your room, but as soon as you will build more complex game/scene with events like instanciating objects in the world space zt runtime, or using static meshes, you will get into bad behaviors. I am still looking for a real nice way to get things aligned with the real world, let me know if you do.

  • Hi, It would be better if you posted this as a comment :) – Deera Wijesundara Jun 11 '23 at 17:06
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/34527963) – James Jun 13 '23 at 23:13