private void GrabByAnchor(IGrabAnchor anchor) { Grabbable grabbed = anchor.Grabbable; _grabbed = grabbed; if (grabbed.GrabbedBySecond == this) { // The first hand to grab will control the object for both hands grabbed.GrabbedBy.SetSecondGrab(anchor, _attacher.Target); } else { // Control the object to follow the hand SetGrab(_grabbed.Body, anchor); } _solidHandMover.Anchor = anchor; _handColliders.SetActive(false); if (_grabbed.GrabPoseID != 0) { SetHandPose(_grabbed.GrabPoseID, true); } // Grab was successful, so we are done OnGrabBegin?.Invoke(grabbed); ClearProximityPose(); }
private void SelectAnchorAndGrab() { if (_canGrab.Count > 1) { SortGrabbables(); } for (int i = 0, len = _canGrab.Count; i < len; i++) { var item = _canGrab[i]; if (item.distance > MaxRadius) { return; } Grabbable grabbed = item.grabbable; IGrabAnchor anchor; #pragma warning disable 618 // Allow use of internal method Grabbable.TryGrab() if (grabbed.TryGrab(this, out anchor)) #pragma warning restore 618 { GrabByAnchor(anchor); return; } // Grab was unsuccessful, so try the next closest anchor //Debug.Log($"COULD NOT GRAB {grabbed.name} ...next!"); } }
private void CacheOffsetOrient(ref Vector3 offset1, ref Quaternion orient1, ref Vector3 offset2, ref Quaternion orient2) { _grabbable = GetComponentInParent <Grabbable>(); if (!_grabbable) { return; } _grabbableXform = _grabbable.transform; var grot = _grabbableXform.eulerAngles; var invGrot = Quaternion.Inverse(_grabbableXform.rotation); offset1 = invGrot * (_xform.position - _grabbableXform.position); orient1 = invGrot * _xform.rotation; var orientEulers = orient1.eulerAngles; if (_mirrorForOtherHand) { offset2 = offset1; if ((_mirrorActions & MirrorAction.InvertOffsetX) > 0) { offset2.x *= -1f; } if ((_mirrorActions & MirrorAction.InvertOffsetY) > 0) { offset2.y *= -1f; } if ((_mirrorActions & MirrorAction.InvertOffsetZ) > 0) { offset2.z *= -1f; } var rotX = (_mirrorActions & MirrorAction.InvertRotationX) > 0; var rotY = (_mirrorActions & MirrorAction.InvertRotationY) > 0; var rotZ = (_mirrorActions & MirrorAction.InvertRotationZ) > 0; if (rotX || rotY || rotZ) { if (rotX) { orientEulers.x *= -1f; } if (rotY) { orientEulers.y *= -1f; } if (rotZ) { orientEulers.z *= -1f; } orient2 = Quaternion.Euler(orientEulers); } else { orient2 = orient1; } } }
private void EndGrab() { SetHandPose(_grabbed.GrabPoseID, false); if (_grabbed.GrabbedBySecond == this) { // This is the second hand being released. Clear second grab from the first's joint _grabbed.GrabbedBy.SetSecondGrab(null, null); } else if (_grabbed.GrabbedBySecond != null) { // This is the first hand being released. The second must now use its own joint to grab _grabbed.GrabbedBySecond.SetGrab(_grabbed.Body, _attacher.SecondAnchor); } var grabbed = _grabbed; _grabbed = null; grabbed.Release(this); SetGrab(null, null); SetSecondGrab(null, null); _solidHandMover.Anchor = null; OnGrabEnd?.Invoke(grabbed); }