统一镜像Oculus Rift控制器位置以进行双边运动 [英] Mirroring Oculus Rift controller positions in unity for bilateral movement

查看:72
本文介绍了统一镜像Oculus Rift控制器位置以进行双边运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我正在尝试编写一个脚本,以将只有一个功能臂的用户将一个控制器的运动镜像到另一个控制器。如何将一个控制器的位置镜像到另一个控制器上,以使手臂处于双向运动状态?

Currently I am trying to write a script that will mirror the movements of one controller onto the other for users who only have 1 functioning arm. How do I mirror the position of the one controller onto the other that way the arms are in bilateral movement?

由于y轴和z轴一起移动,因此很容易镜像而且旋转很容易反映出来。我无法反映x轴的运动。我想要这样,以便如果一只手伸出另一只手也一样,并且它们都一起移动。有什么想法我可能能够做到这一点吗?我已附上当前脚本。 我还使用OVRCemeraRig脚本中的简单布尔逻辑禁用了非镜像控制器的位置跟踪,以防止出现卡顿现象 由于使用了最终IK,因此需要使用OVRCemeraRig

Mirroring the y axis and z axis were easy since they move together and the rotation was easy to mirror. I am unable to mirror the x axis movement. I want it so that if the one hand moves out the other does the same, and they both move in together. Any ideas how I may be able to do this? I have attached my current script. I also disabled the position tracking of the non mirrored controller with simple Boolean logic in the OVRCemeraRig script to prevent stutters in movement Need to use OVRCemeraRig since using final IK

我尝试对工作臂的x位置求差,然后将该值添加到不工作臂。

I have tried taking a difference in the x positions in the working arm and then adding that value to the none working arm. That did not work.

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;

        }
    }
}


推荐答案

为了稳健起见,让我们假设玩家的身体旋转不一定总是正确地指向(1,0,0)世界方向。取而代之的是,我们可以引用玩家的Transform, playerTransform (请务必使用检查器或在开始

For the sake of robustness, let's assume your player's body's rotation might not necessarily always have its right pointing in the (1,0,0) world direction. Instead, we can get a reference to the player's Transform, playerTransform, (be sure to assign it using the inspector or in Start if you must) and make our calculations using that.

要计算相对矢量的双边对称位置,可以计算 relativeVec- 2f * playerTransform.right * Vector3.Dot(relativeVec,playerTransform.right);

To calculate the bilateral symmetric position for a relative vector, you can calculate relativeVec - 2f * playerTransform.right * Vector3.Dot(relativeVec, playerTransform.right);. Explanation for why that works is in the comments.

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

For position, we can convert the absolute position of the source hand to be relative to the player's position, then find the relative position of the destination hand, then convert that back into an absolute position.

要进行旋转,请确定向上和向下。向前伸出源头,并反射它们以确定上升和下降。前进到目的地手。使用 Quaternion.SetLookRotation 将矢量转换为目标手的旋转。

For rotation, determine up & forward for the source hand and reflect them to determine the up & forward for the destination hand. Use Quaternion.SetLookRotation to convert the vectors to the rotation for the destination hand.

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

We can use the same code for relative positions and for our direction vectors, so it actually doesn't take much code once you have the math. And also, since Transform is a class, we can make one method that does the reflection procedure, and then pass into it which transforms we want to be the source and destination:

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;
    }
}

这篇关于统一镜像Oculus Rift控制器位置以进行双边运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆