1

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: enter image description here

Afroca
  • 115
  • 11
  • 1
    I'm afraid I can't help here much, but from what I can see in [the docs](https://developer.oculus.com/documentation/unity/latest/concepts/unity-utilities-overview/?locale=en_US) it looks like you want `OVRGrabbable` components on the plate and a `OVRGrabber` on each hand. When a grab is established, I would set the VRMirror's `vrMirror.enabled=false;` and parent the hand to some child of the plate. Then when the grab ends, put it back to the original parent and then enable the VRMirror component again with `vrMirror.enabled=true;`. – Ruzihm Jul 30 '19 at 18:51
  • @Ruzihm I may go back and try that. I created a solution that based on the OvrCameraRig when an object is grabbed it will only take the inputs of the axis I need. But when I let go of the object the hands will snap to the positions they are supposed to be in. I will post my solution – Afroca Jul 30 '19 at 19:08

1 Answers1

0

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.

Afroca
  • 115
  • 11
  • you also have to be careful with directly making changes in `OVRCamerRig` it will be overwritten with the next update. Maybe it would be better to inherit from it instead and only overwrite the virtual `UpdateAnchors` method – derHugo Jul 31 '19 at 06:16
  • @derHugo I will have to learn about how to do that. I have been backing up the scripts all the time in case of an update. – Afroca Jul 31 '19 at 13:07
  • You would simply create your own script like `public class CustomOVRCameraRig : OVRCameraRig { public override void UpdateAnchors() { YOUR CODE HERE } }` ;) Btw I don't quote understand the last comment about `the issue I am still having` .. what would you like to happen instead as this simply **is** the rotation the user is holding the hands in ...? – derHugo Aug 01 '19 at 04:09