Unity Oculus将手的位置锁定在1个轴上,同时在抓取对象时允许其他方向移动 [英] Unity Oculus locking hand positions in 1 axis while allowing for movement in the others when grabbing objects

查看:196
本文介绍了Unity Oculus将手的位置锁定在1个轴上,同时在抓取对象时允许其他方向移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当试图抓住一个对象时,我试图将模型的手锁定到一个对象上.目前,我项目中的对象已被锁定,仅在抓取时允许其在Y轴和Z轴上移动.我想在抓住物体时将玩家的手的位置锁定在X轴上,但是放开时返回常规的手部追踪. (例如,在VR中抓住门把手,您希望手一直固定在门把手上直到松开)

I am trying to lock the models hands to an object when an object is grabbed. Currently the object in my project has been locked to only allow for movement in the Y and Z axis when it is grabbed. I want to lock the players hand position in the X axis when the object is grabbed but return to regular hand tracking when released. (An Example of this is grabbing a door knob in VR, you want the hand to stay fixed to the door knob until released)

我尝试过将手作为对象的对象,但我可能做得不好.我对OVRGrabber脚本进行了一些修改,以与我的项目一起使用.以下示例代码已添加到VRMirror脚本中,可在此处找到.在固定更新的末尾调用lockHands().

I have tried playing around with parenting the hands to the object but I may have not done it right. I have made some modifications to the OVRGrabber script to work with my project. The sampled code below is being added to the VRMirror script which can be found here. lockHands() is called at the end of the fixed update.

    void lockHands()
    {
         if(L_GrabbedObject.GetComponent<OVRGrabber>().isGrabbed || R_GrabbedObject.GetComponent<OVRGrabber>().isGrabbed)
         {

            if (mirrorLeft)
            {
                string name = L_GrabbedObject.GetComponent<OVRGrabber>().m_grabbedObj.name;
                Debug.Log(name + " Left");
            }
            else if (mirrorRight)
            {
                var objGrabbed = R_GrabbedObject.GetComponent<OVRGrabber>().m_grabbedObj;
                string name = objGrabbed.name;
                Debug.Log(name + " Right");
            }
        }
    }

我需要这部分与双边镜像脚本以及OVRGrabber和OVRCameraRig一起使用.

I need this part to work along side the Bilateral mirroring script as well with the OVRGrabber and OVRCameraRig.

Plate是要抓取的对象.这是该项目的屏幕截图:

Plate is the object being grabbed. Here is a screenshot of the project:

推荐答案

我提出的解决方案使用OVRCameraRig脚本.我在UpdateAnchors()方法中对该脚本进行了大量更改.

The solution I came up with uses the OVRCameraRig script. I made a bunch of changes to that scrip in the UpdateAnchors() method.

    var mirror = GameObject.Find("OVRCameraRig").GetComponent<VRMirror>();
    var L_GrabbedObject = GameObject.Find("Left Hand Target").GetComponent<OVRGrabber>();
    var R_GrabbedObject = GameObject.Find("Right Hand Target").GetComponent<OVRGrabber>();
    //Need this for controller offset because if we're on OpenVR, we want to set the local poses as specified by Unity, but if we're not, OVRInput local position is the right anchor
    if (OVRManager.loadedXRDevice == OVRManager.XRDevice.OpenVR)
    {
        Vector3 leftPos = Vector3.zero;
        Vector3 rightPos = Vector3.zero;
        Quaternion leftQuat = Quaternion.identity;
        Quaternion rightQuat = Quaternion.identity;


        if (mirror.mirrorLeft)
        {
            if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.LeftHand, NodeStatePropertyType.Position, OVRPlugin.Node.HandLeft, OVRPlugin.Step.Render, out leftPos))
                if(L_GrabbedObject.isGrabbed)
                {
                    if(L_GrabbedObject.m_grabbedObj.name == "rollingPin")
                    {
                        Vector3 leftHand = leftHandAnchor.localPosition;
                        leftHand.z = leftPos.z;
                        leftHandAnchor.localPosition = leftHand;
                    }
                }else
                {
                    leftHandAnchor.localPosition = leftPos;
                }

            if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.LeftHand, NodeStatePropertyType.Orientation, OVRPlugin.Node.HandLeft, OVRPlugin.Step.Render, out leftQuat))
                if (!L_GrabbedObject.isGrabbed)
                    leftHandAnchor.localRotation = leftQuat;
        }else if (mirror.mirrorRight)
        {
            if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.RightHand, NodeStatePropertyType.Position, OVRPlugin.Node.HandRight, OVRPlugin.Step.Render, out rightPos))
                if (R_GrabbedObject.isGrabbed)
                {
                    if (R_GrabbedObject.m_grabbedObj.name == "rollingPin")
                    {
                        Vector3 rightHand = rightHandAnchor.localPosition;
                        rightHand.z = rightPos.z;
                        rightHandAnchor.localPosition = rightHand;
                    }
                }
                else
                {
                    rightHandAnchor.localPosition = rightPos;
                }
            if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.RightHand, NodeStatePropertyType.Orientation, OVRPlugin.Node.HandRight, OVRPlugin.Step.Render, out rightQuat))
                if (!R_GrabbedObject.isGrabbed)
                {
                    rightHandAnchor.localRotation = rightQuat;
                }
        }
    }
    else
    {
        if (mirror.mirrorLeft)
        {
            if (L_GrabbedObject.isGrabbed)
            {
                if (L_GrabbedObject.m_grabbedObj.name == "rollingPin")
                {
                    Vector3 leftHand = leftHandAnchor.localPosition;
                    leftHand.z = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch).z;
                    leftHandAnchor.localPosition = leftHand;
                }
            }
            else
            {
                leftHandAnchor.localPosition = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch);
                leftHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.LTouch);
            }


        }else if  (mirror.mirrorRight) {
            if (R_GrabbedObject.isGrabbed)
            {
                if (R_GrabbedObject.m_grabbedObj.name == "rollingPin")
                {
                    Vector3 rightHand = rightHandAnchor.localPosition;
                    rightHand.z = OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch).z;
                    rightHandAnchor.localPosition = rightHand;
                }
            }
            else
            {
                rightHandAnchor.localPosition = OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch);
                rightHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch);
            }


        }
    }

我还必须将OVRGrabber脚本中的m_grabbedObj公开,以及向OVRGrabber脚本中添加了一个公共布尔值,无论是否捕获了对象,该布尔值都将在true和false之间切换. (对象上必须带有OVRGrabbable脚本).

I also had to make the m_grabbedObj from OVRGrabber script public, as well as I added a public bool to the OVRGrabber script that will switch between true and false if an object is grabbed or not. (The object must have the OVRGrabbable script on it).

我检查对象名称的原因是因为某些对象的运动锁定在某些轴上.我的游戏中的盘子只能在Z和Y轴上移动.

The reason I check for the name of the object is because certain objects have their movements locked to certain axis. The plate in my game can only be moved in the Z and Y axis.

我仍然遇到的问题
当您放开对象时,玩家的手将紧贴控制器位于世界的位置.

The issue I am having still
When you let go of the object the hand of the player will snap to the position that the controller is in base on world.

这篇关于Unity Oculus将手的位置锁定在1个轴上,同时在抓取对象时允许其他方向移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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