1

我以 3D 和统一的方式创建了我的房间的 1:1 复制品。现在我想通过 VR 将这个虚拟房间与我的真实房间对齐。所以我在 VR 中看到的桌子与真实的桌子完全匹配。

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

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

链接:https ://twitter.com/IRCSS/status/1231523329183559681/photo/1

4

1 回答 1

2

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

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

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

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

  2. 根据类名调用它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. 在场景的层次结构中,选择要对齐的世界/房间的根网格对象

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

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


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

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

    因此,请确保您的真实世界点 A 与 Unity 中对象的轴心点匹配!

  • 第二次单击用于设置其旋转(因此它的正轴指向 B)和缩放。

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

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

  • None

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

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

  • PivotOneSet

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

    Button One再次按下以设置第二个位置B

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

  • PivotTwoSet

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

于 2020-06-19T09:49:56.823 回答