Unity Oculus locking hand positions in 1 axis while allowing for movement in the others when grabbing objects

你离开我真会死。 提交于 2019-12-11 06:35:23

问题


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)

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

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

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


回答1:


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


        }
    }

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).

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.



来源:https://stackoverflow.com/questions/57275200/unity-oculus-locking-hand-positions-in-1-axis-while-allowing-for-movement-in-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!