void Release() { SnapState = SnapState.Releasing; CurrentlySnappedTo.OnRelease(); CurrentlySnappedTo = null; transform.SetParent(_unsnappedParent, true); _rb.isKinematic = false; SnapState = SnapState.Idle; if (OnRelease != null) { OnRelease(); } }
public IEnumerator SnapCoroutine() { SnapState = SnapState.Snapping; _rb.isKinematic = true; var wasGrabbable = _interactableItem.IsGrabbable; _interactableItem.IsGrabbable = false; yield return(null); if (!CanSnap) { _rb.isKinematic = false; _interactableItem.IsGrabbable = wasGrabbable; _snapCoroutine = null; SnapState = SnapState.Idle; yield break; } SnapTarget snapTarget = _targetsInRange.Where(target => target.CurrentlySnapped == null).OrderBy(target => Quaternion.Angle(transform.rotation, target.transform.rotation)).First(); //Making sure the item is handled correctly with the hands. _interactableItem.DisableCollision(); _interactableItem.Detach(); _rb.isKinematic = true; snapTarget.OnSnap(this); Vector3 targetScale = Vector3.one; switch (ScaleBehaviour) { case ScaleBehaviour.RetainScale: targetScale = transform.localScale; break; case ScaleBehaviour.InheritFromTarget: targetScale = snapTarget.transform.localScale; break; case ScaleBehaviour.CustomScale: targetScale = _customScale; break; default: throw new ArgumentOutOfRangeException(); } //Bind funcs to prevent code repetition. Func <float> getDist = () => Vector3.Distance(transform.position, snapTarget.transform.position); Func <float> getAngle = () => Quaternion.Angle(transform.rotation, snapTarget.transform.rotation); //Calculate what amount of translation and rotation should be applied per frame. float angleDelta = getAngle() / (SnapTime / Time.fixedDeltaTime); float distDelta = getDist() / (SnapTime / Time.fixedDeltaTime); //Setting the transform to the target transform over a certain time. while (getDist() > 0.0001f || getAngle() > 0.001f) { transform.position = Vector3.MoveTowards(transform.position, snapTarget.transform.position, distDelta); transform.rotation = Quaternion.RotateTowards(transform.rotation, snapTarget.transform.rotation, angleDelta); if (ScaleBehaviour != ScaleBehaviour.RetainScale) { transform.localScale = Vector3.MoveTowards(transform.localScale, targetScale, distDelta); } yield return(new WaitForFixedUpdate()); } _interactableItem.EnableCollision(); CurrentlySnappedTo = snapTarget; transform.SetParent(snapTarget.transform, true); SnapState = SnapState.Snapped; if (OnSnap != null) { OnSnap(); } yield return(new WaitUntil(() => _detectors.Sum(detector => detector.GetCollidingObjectsInLayer(Layer.Phalange).Count()) == 0)); _interactableItem.IsGrabbable = wasGrabbable; _snapCoroutine = null; }