Oculus Quest - 真实世界对齐

Oculus Quest - Real World Alignment

我在 3D 和 unity 中创建了我房间的 1:1 副本。现在我想通过 VR 将这个虚拟房间与我的真实房间对齐。 所以我在 VR 中看到的 Table 和真实的一模一样。

但由于我使用的是 Oculus Quest,它会在每次启动时重新计算其位置,因此无法精确对齐世界。

但是,我找到了一个脚本,它应该允许我将我的 VR 耳机与我房间的网格重新居中。 我唯一的问题是,我没有开发背景,代码片段的简短解释对我来说不够详细。 有人可以向我解释该做什么以及将代码放在我的场景中的什么位置吗?

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

你的问题很宽泛。一般来说,而是询问脚本的制作者如何使用它;)

但简而言之,使用这样的脚本:(顺便说一句,在您的 link 评论中,您会看到其余代码)。

  1. 在资源中创建一个新脚本

    ProjectView -> 右键单击 -> Create -> C# Script

  2. 根据 class 名称调用它 AlignMesh

  3. 双击打开

  4. 过去的代码。

    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. 在场景的层次结构中 select 您要对齐的 world/room 的根网格对象

  6. 在检查器中单击 Add Component 并搜索您创建的 AlignMesh

  7. leftHandPosition 从 OVR 装备中拖放相应的手。并在 ABDistance 中调整两个点击位置之间的实际距离(以米为单位)。


稍微解释一下这是做什么的:

  • 第一次点击将房间设置到该位置

    所以请确保你的真实世界点A与Unity中物体的轴心点相匹配!

  • 第二次点击用于设置它的旋转(所以它的前向轴指向B)和缩放。

    因此请确保您的现实世界点 B 与 A 对齐,因此该方向与您的网格 FORWARD 轴匹配

它如何在代码基础上工作:

  • None

    最初您处于空闲状态 None,您的脚本仅等待点击 Button.One

    一旦你按下按钮,房间就会被设置到相应的位置,你会去到PivotOneSet

  • PivotOneSet

    现在您正在等待 Button Two 按 => 取消 => 回到 None 状态

    或者您再次按 Button One 设置第二个位置 B

    设置第二个位置后,您可以调整房间的方向和比例以匹配真实世界的坐标。然后你进入PivotTwoSet状态。

  • PivotTwoSet

    除了等待 Button Two 单击以通过返回 None 状态重新初始化设置过程外,这基本上什么都不做。