private void OffhandGrabbed(Grabbable grabbable) { if (m_grabbedObj == grabbable) { GrabbableRelease(Vector3.zero, Vector3.zero); } }
private void OnTriggerExit(Collider otherCollider) { Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>(); 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); } }
private void GrabbableRelease(Vector3 linearVelocity, Vector3 angularVelocity) { Destroy(gameObject.GetComponent <FixedJoint>()); m_grabbedObj.GrabEnd(linearVelocity, angularVelocity); if (m_parentHeldObject) { m_grabbedObj.transform.parent = null; } m_grabbedObj = null; }
public void ForceRelease(Grabbable grabbable) { bool canRelease = ( (m_grabbedObj != null) && (m_grabbedObj == grabbable) ); if (canRelease) { GrabEnd(); } }
private void OnTriggerEnter(Collider otherCollider) { // Get the grab trigger Grabbable grabbable = otherCollider.GetComponent <Grabbable>() ?? otherCollider.GetComponentInParent <Grabbable>(); if (grabbable == null) { return; } // Add the grabbable int refCount = 0; m_grabCandidates.TryGetValue(grabbable, out refCount); m_grabCandidates[grabbable] = refCount + 1; }
private void GrabBegin() { float closestMagSq = float.MaxValue; Grabbable closestGrabbable = null; Collider closestGrabbableCollider = null; // Iterate grab candidates and find the closest grabbable candidate foreach (Grabbable 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); if (m_useFixedJointForGrabbedObject) { FixedJoint fj = gameObject.GetComponent <FixedJoint>() ?? gameObject.AddComponent <FixedJoint>(); fj.connectedBody = m_grabbedObj.GetComponent <Rigidbody>(); } else { 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; } } } }
private void GrabBegin() { float closestMagSq = float.MaxValue; Grabbable closestGrabbable = null; Collider closestGrabbableCollider = null; // Iterate grab candidates and find the closest grabbable candidate foreach (Grabbable 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); if (m_useFixedJointForGrabbedObject) { FixedJoint fj = gameObject.GetComponent <FixedJoint>() ?? gameObject.AddComponent <FixedJoint>(); fj.connectedBody = m_grabbedObj.GetComponent <Rigidbody>(); } else { // 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. m_lastPos = transform.position; m_lastRot = transform.rotation; MoveGrabbedObject(true); if (m_parentHeldObject) { m_grabbedObj.transform.parent = transform; } } } }