protected virtual void OffhandGrabbed(GrabbableHands grabbable) { if (m_grabbedObj == grabbable) { GrabbableRelease(Vector3.zero, Vector3.zero); } }
void OnTriggerExit(Collider otherCollider) { GrabbableHands grabbable = otherCollider.GetComponent <GrabbableHands>() ?? otherCollider.GetComponentInParent <GrabbableHands>(); if (grabbable == null) { return; } // Remove the grabbable int refCount = 0; bool found = m_grabCandidates.TryGetValue(grabbable, out refCount); if (!found) { return; } if (refCount > 1) { m_grabCandidates[grabbable] = refCount - 1; } else { m_grabCandidates.Remove(grabbable); } }
protected void GrabbableRelease(Vector3 linearVelocity, Vector3 angularVelocity) { m_grabbedObj.GrabEnd(linearVelocity, angularVelocity); if (m_parentHeldObject) { m_grabbedObj.transform.parent = null; } m_grabbedObj = null; }
public void ForceRelease(GrabbableHands grabbable) { bool canRelease = ( (m_grabbedObj != null) && (m_grabbedObj == grabbable) ); if (canRelease) { GrabEnd(); } }
void OnTriggerEnter(Collider otherCollider) { // Get the grab trigger GrabbableHands grabbable = otherCollider.GetComponent <GrabbableHands>() ?? otherCollider.GetComponentInParent <GrabbableHands>(); if (grabbable == null) { return; } if (m_grabCandidates.ContainsKey(grabbable)) { return; } // Add the grabbable int refCount = 0; m_grabCandidates.TryGetValue(grabbable, out refCount); m_grabCandidates[grabbable] = refCount + 1; }
protected virtual void GrabBegin() { float closestMagSq = float.MaxValue; GrabbableHands closestGrabbable = null; Collider closestGrabbableCollider = null; // Iterate grab candidates and find the closest grabbable candidate foreach (GrabbableHands 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); if (m_parentHeldObject) { m_grabbedObj.transform.parent = transform; } } }