Example #1
0
        void Release()
        {
            SnapState = SnapState.Releasing;
            CurrentlySnappedTo.OnRelease();
            CurrentlySnappedTo = null;
            transform.SetParent(_unsnappedParent, true);
            _rb.isKinematic = false;
            SnapState       = SnapState.Idle;

            if (OnRelease != null)
            {
                OnRelease();
            }
        }
Example #2
0
        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;
        }