/// <summary> /// Stops the interpolation regardless if it has reached the target /// </summary> public void StopInterpolating() { if (enabled) { Reset(); InterpolationDone?.Invoke(); } }
/// <summary> /// Snaps to the final target and stops interpolating /// </summary> public void SnapToTarget() { if (enabled) { transform.position = TargetPosition; transform.rotation = TargetRotation; transform.localRotation = TargetLocalRotation; transform.localScale = TargetLocalScale; AnimatingPosition = false; AnimatingLocalScale = false; AnimatingRotation = false; AnimatingLocalRotation = false; enabled = false; InterpolationDone?.Invoke(); } }
private void Update() { float deltaTime = useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime; bool interpOccuredThisFrame = false; if (AnimatingPosition) { Vector3 lerpTargetPosition = targetPosition; if (SmoothLerpToTarget) { lerpTargetPosition = Vector3.Lerp(transform.position, lerpTargetPosition, SmoothPositionLerpRatio); } Vector3 newPosition = NonLinearInterpolateTo(transform.position, lerpTargetPosition, deltaTime, positionPerSecond); if ((targetPosition - newPosition).sqrMagnitude <= Tolerance) { // Snap to final position newPosition = targetPosition; AnimatingPosition = false; } else { interpOccuredThisFrame = true; } transform.position = newPosition; //calculate interpolatedVelocity and store position for next frame PositionVelocity = oldPosition - newPosition; oldPosition = newPosition; } // Determine how far we need to rotate if (AnimatingRotation) { Quaternion lerpTargetRotation = targetRotation; if (SmoothLerpToTarget) { lerpTargetRotation = Quaternion.Lerp(transform.rotation, lerpTargetRotation, SmoothRotationLerpRatio); } float angleDiff = Quaternion.Angle(transform.rotation, lerpTargetRotation); float speedScale = 1.0f + (Mathf.Pow(angleDiff, rotationSpeedScaler) / 180.0f); float ratio = Mathf.Clamp01((speedScale * rotationDegreesPerSecond * deltaTime) / angleDiff); if (angleDiff < Mathf.Epsilon) { AnimatingRotation = false; transform.rotation = targetRotation; } else { // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f transform.rotation = Quaternion.Slerp(transform.rotation, lerpTargetRotation, ratio); interpOccuredThisFrame = true; } } // Determine how far we need to rotate if (AnimatingLocalRotation) { Quaternion lerpTargetLocalRotation = targetLocalRotation; if (SmoothLerpToTarget) { lerpTargetLocalRotation = Quaternion.Lerp(transform.localRotation, lerpTargetLocalRotation, SmoothRotationLerpRatio); } float angleDiff = Quaternion.Angle(transform.localRotation, lerpTargetLocalRotation); float speedScale = 1.0f + (Mathf.Pow(angleDiff, rotationSpeedScaler) / 180.0f); float ratio = Mathf.Clamp01((speedScale * rotationDegreesPerSecond * deltaTime) / angleDiff); if (angleDiff < Mathf.Epsilon) { AnimatingLocalRotation = false; transform.localRotation = targetLocalRotation; } else { // Only lerp rotation here, as ratio is NaN if angleDiff is 0.0f transform.localRotation = Quaternion.Slerp(transform.localRotation, lerpTargetLocalRotation, ratio); interpOccuredThisFrame = true; } } if (AnimatingLocalScale) { Vector3 lerpTargetLocalScale = targetLocalScale; if (SmoothLerpToTarget) { lerpTargetLocalScale = Vector3.Lerp(transform.localScale, lerpTargetLocalScale, SmoothScaleLerpRatio); } Vector3 newScale = NonLinearInterpolateTo(transform.localScale, lerpTargetLocalScale, deltaTime, scalePerSecond); if ((targetLocalScale - newScale).sqrMagnitude <= Tolerance) { // Snap to final scale newScale = targetLocalScale; AnimatingLocalScale = false; } else { interpOccuredThisFrame = true; } transform.localScale = newScale; } // If all interpolations have completed, stop updating if (!interpOccuredThisFrame) { InterpolationDone?.Invoke(); enabled = false; } }