protected virtual void GrabBegin() { float closestMagSq = float.MaxValue; OVRGrabbable closestGrabbable = null; Collider closestGrabbableCollider = null; // Iterate grab candidates and find the closest grabbable candidate foreach (OVRGrabbable grabbable in m_grabCandidates.Keys) { bool canGrab = !(grabbable.isGrabbed && !grabbable.allowOffhandGrab); if (!canGrab) { continue; } for (int j = 0; j < grabbable.grabPoints.Length; ++j) { Collider grabbableCollider = grabbable.grabPoints[j]; // Store the closest grabbable Vector3 closestPointOnBounds = grabbableCollider.ClosestPointOnBounds(m_gripTransform.position); float grabbableMagSq = (m_gripTransform.position - closestPointOnBounds).sqrMagnitude; if (grabbableMagSq < closestMagSq) { closestMagSq = grabbableMagSq; closestGrabbable = grabbable; closestGrabbableCollider = grabbableCollider; } } } // Disable grab volumes to prevent overlaps GrabVolumeEnable(false); if (closestGrabbable != null) { if (closestGrabbable.isGrabbed) { closestGrabbable.grabbedBy.OffhandGrabbed(closestGrabbable); } m_grabbedObj = closestGrabbable; m_grabbedObj.GrabBegin(this, closestGrabbableCollider); m_lastPos = transform.position; m_lastRot = transform.rotation; // Set up offsets for grabbed object desired position relative to hand. if (m_grabbedObj.snapPosition) { m_grabbedObjectPosOff = m_gripTransform.localPosition; if (m_grabbedObj.snapOffset) { Vector3 snapOffset = m_grabbedObj.snapOffset.position; if (m_controller == OVRInput.Controller.LTouch) { snapOffset.x = -snapOffset.x; } m_grabbedObjectPosOff += snapOffset; } } else { Vector3 relPos = m_grabbedObj.transform.position - transform.position; relPos = Quaternion.Inverse(transform.rotation) * relPos; m_grabbedObjectPosOff = relPos; } if (m_grabbedObj.snapOrientation) { m_grabbedObjectRotOff = m_gripTransform.localRotation; if (m_grabbedObj.snapOffset) { m_grabbedObjectRotOff = m_grabbedObj.snapOffset.rotation * m_grabbedObjectRotOff; } } else { Quaternion relOri = Quaternion.Inverse(transform.rotation) * m_grabbedObj.transform.rotation; m_grabbedObjectRotOff = relOri; } // NOTE: force teleport on grab, to avoid high-speed travel to dest which hits a lot of other objects at high // speed and sends them flying. The grabbed object may still teleport inside of other objects, but fixing that // is beyond the scope of this demo. MoveGrabbedObject(m_lastPos, m_lastRot, true); // NOTE: This is to get around having to setup collision layers, but in your own project you might // choose to remove this line in favor of your own collision layer setup. SetPlayerIgnoreCollision(m_grabbedObj.gameObject, true); if (m_parentHeldObject) { m_grabbedObj.transform.parent = transform; } PickUpManager.ItemPickedUp(m_grabbedObj.gameObject); } }