c# - 为双边移动统一镜像 Oculus Rift Controller 位置

标签 c# unity3d vector accessibility oculus

目前,我正在尝试编写一个脚本,为只有一个功能 ARM 的用户将一个 Controller 的 Action 映射到另一个 Controller 上。我如何将一个 Controller 的位置镜像到另一个 Controller ,使 ARM 在双边运动中?

镜像 y 轴和 z 轴很容易,因为它们一起移动并且旋转很容易镜像。我无法镜像 x 轴运动。我想要这样,如果一只手移出,另一只手也移出,并且它们一起移入。有什么想法我可以做到这一点吗?我附上了我目前的剧本。 我还在 OVRCemeraRig 脚本中使用简单的 bool 逻辑禁用了非镜像 Controller 的位置跟踪,以防止运动中的卡顿 需要使用 OVRCemeraRig,因为使用了最终 IK

我试过在工作臂的 x 位置上取一个差异,然后将该值添加到非工作臂。那没有用。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VRMirror : MonoBehaviour
{
    public bool mirrorLeft;
    public bool mirrorRight;
    public GameObject leftHand; //left hand anchor in OVRCameraRig
    public GameObject rightHand; //right hand anchor from OVRCameraRig
    void Start()
    {

    }
    void FixedUpdate()
    {
        Transform left = leftHand.GetComponent<Transform>();
        Transform right = rightHand.GetComponent<Transform>();
        if (mirrorLeft)
        {
            Vector3 leftPos = left.position;
            Quaternion leftRot = left.rotation;
            leftRot.y = -leftRot.y;
            right.position = leftPos;
            right.rotation = leftRot;
        }
        else if (mirrorRight)
        {
            Vector3 rightPos = right.position;
            Quaternion rightRot = right.rotation;

            rightRot.y = -rightRot.y;
            left.position = rightPos;
            left.rotation = rightRot;

        }
    }
}

最佳答案

为了稳健性,我们假设玩家的 body 旋转不一定总是正确指向 (1,0,0) 世界方向。相反,我们可以获得对玩家转换 playerTransform 的引用(如果必须,请务必使用检查器或在 Start 中分配它)并使用它进行计算.

要计算相对向量的双边对称位置,您可以计算 relativeVec - 2f * playerTransform.right * Vector3.Dot(relativeVec, playerTransform.right);。评论中解释了为什么这样做。

对于位置,我们可以将源手的绝对位置转换为相对于玩家位置的位置,然后找到目标手的相对位置,然后将其转换回绝对位置。

对于旋转,确定源手的向上和向前并反射(reflect)它们以确定目标手的向上和向前。使用 Quaternion.SetLookRotation 将矢量转换为目标手的旋转。

我们可以对相对位置和我们的方向向量使用相同的代码,所以一旦你掌握了数学,它实际上不需要太多代码。而且,由于 Transform 是一个类,我们可以创建一个执行反射过程的方法,然后将其传递给我们希望成为源和目标的转换:

public class VRMirror : MonoBehaviour
{
    public bool mirrorLeft;
    public bool mirrorRight;
    public GameObject leftHand; //left hand anchor in OVRCameraRig
    public GameObject rightHand; //right hand anchor from OVRCameraRig

    public Transform playerTransform;

    void Start()
    {

    }
    void FixedUpdate()
    {

        Transform left = leftHand.GetComponent<Transform>();
        Transform right = rightHand.GetComponent<Transform>();
        if (mirrorLeft)
        {
            MirrorFromTo(left, right);
        }
        else if (mirrorRight)
        {
            MirrorFromTo(right, left);
        }
    }

    void MirrorFromTo(Transform sourceTransform, Transform destTransform)
    {
        // Determine dest position
        Vector3 playerToSourceHand = sourceTransform.position - playerTransform.position;
        Vector3 playerToDestHand = ReflectRelativeVector(playerToSourceHand);
        destTransform.position = playerTransform.position + playerToDestHand ;

        // Determine dest rotation
        Vector3 forwardVec = ReflectRelativeVector(sourceTransform.forward);
        Vector3 upVec = ReflectRelativeVector(sourceTransform.up);
        destTransform.rotation = Quaternion.LookRotation(forwardVec,upVec);
    }

    Vector3 ReflectRelativeVector(Vector3 relativeVec) 
    {
       // relativeVec
       //     Take the relative vector....
       // + Vector3.Dot(relativeVec, playerTransform.right)
       //     and for how far along the player's right direction it is 
       //     away from the player (may be negative),
       // * playerTransform.right
       //     move it that distance along the player's right...
       // * -2f
       //    negative two times (i.e., along the left direction 2x)

       return relativeVec 
           + Vector3.Dot(relativeVec, playerTransform.right)
               * playerTransform.right 
               * -2f;
    }
}

关于c# - 为双边移动统一镜像 Oculus Rift Controller 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57013289/

相关文章:

c# - 未注册类型的 SimpleInjector 强制 Lifestyle.Transient

C# 在 vi​​sual studio 中使用重定向运算符

c# - 有没有办法找到 C# 程序集引用的类型?

C++ - 使用类参数定义 vector 大小

math - 棘手的柏林噪声问题。 Grad 函数如何使用归一化向量?

c# - 无法在 VS 2010 中编译 WebKit .NET 0.5

unity3d - 统一 5 : Automatically specifying the triangle list for the vertices of a mesh

c# - 用于 C# mono 和 Unity3d 的 Consulo IDE,是否可行?

c# - 2D 角色在流畅的相机中卡顿

c++ - C4018 : Signed, 类内无符号不匹配