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
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).
Create a new script within the Assets
ProjectView
-> Right Click -> Create
-> C# Script
Call it accoding to the class name AlignMesh
Double click to open it
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;
}
}
}
In your scene's Hierarchy select your root mesh object of the world/room you want to align
In the Inspector click Add Component
and search for your created AlignMesh
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.