/// <summary> /// Springs a float towards a target value /// </summary> /// <param name="currentValue">the current value to spring, passed as a ref</param> /// <param name="targetValue">the target value we're aiming for</param> /// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param> /// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param> /// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param> /// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param> /// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param> public static void Spring(ref float currentValue, float targetValue, ref float velocity, float damping, float frequency, float speed, float deltaTime) { float initialVelocity = velocity; velocity = SpringVelocity(currentValue, targetValue, velocity, damping, frequency, speed, deltaTime); velocity = MMMaths.Lerp(initialVelocity, velocity, speed, Time.deltaTime); currentValue += deltaTime * velocity; }
/// <summary> /// Springs a Vector2 towards a target value /// </summary> /// <param name="currentValue">the current value to spring, passed as a ref</param> /// <param name="targetValue">the target value we're aiming for</param> /// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param> /// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param> /// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param> /// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param> /// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param> public static void Spring(ref Vector2 currentValue, Vector2 targetValue, ref Vector2 velocity, float damping, float frequency, float speed, float deltaTime) { Vector2 initialVelocity = velocity; velocity.x = SpringVelocity(currentValue.x, targetValue.x, velocity.x, damping, frequency, speed, deltaTime); velocity.y = SpringVelocity(currentValue.y, targetValue.y, velocity.y, damping, frequency, speed, deltaTime); velocity.x = MMMaths.Lerp(initialVelocity.x, velocity.x, speed, Time.deltaTime); velocity.y = MMMaths.Lerp(initialVelocity.y, velocity.y, speed, Time.deltaTime); currentValue += deltaTime * velocity; }
/// <summary> /// Follows the target, lerping the position or not based on what's been defined in the inspector /// </summary> protected virtual void FollowTargetPosition() { if (Target == null) { return; } if (!FollowPosition) { return; } _newTargetPosition = Target.position + Offset; if (!FollowPositionX) { _newTargetPosition.x = _initialPosition.x; } if (!FollowPositionY) { _newTargetPosition.y = _initialPosition.y; } if (!FollowPositionZ) { _newTargetPosition.z = _initialPosition.z; } float trueDistance = 0f; _direction = (_newTargetPosition - this.transform.position).normalized; trueDistance = Vector3.Distance(this.transform.position, _newTargetPosition); float interpolatedDistance = trueDistance; if (InterpolatePosition) { interpolatedDistance = MMMaths.Lerp(0f, trueDistance, FollowPositionSpeed); } if (UseMinimumDistanceBeforeFollow && (trueDistance - interpolatedDistance < MinimumDistanceBeforeFollow)) { interpolatedDistance = 0f; } if (UseMaximumDistance && (trueDistance - interpolatedDistance >= MaximumDistance)) { interpolatedDistance = trueDistance - MaximumDistance; } this.transform.Translate(_direction * interpolatedDistance, Space.World); }
/// <summary> /// Makes the object follow its target's rotation /// </summary> protected virtual void FollowTargetRotation() { if (Target == null) { return; } if (!FollowRotation) { return; } _newTargetRotation = Target.rotation; if (InterpolateRotation) { this.transform.rotation = MMMaths.Lerp(this.transform.rotation, _newTargetRotation, FollowRotationSpeed); } else { this.transform.rotation = _newTargetRotation; } }
/// <summary> /// Makes the object follow its target's scale /// </summary> protected virtual void FollowTargetScale() { if (Target == null) { return; } if (!FollowScale) { return; } _newScale = Target.localScale * FollowScaleFactor; if (InterpolateScale) { switch (FollowScaleMode) { case FollowModes.MMLerp: this.transform.localScale = MMMaths.Lerp(this.transform.localScale, _newScale, FollowScaleSpeed, Time.deltaTime); break; case FollowModes.RegularLerp: this.transform.localScale = Vector3.Lerp(this.transform.localScale, _newScale, Time.deltaTime * FollowScaleSpeed); break; case FollowModes.MMSpring: this.transform.localScale = MMMaths.Lerp(this.transform.localScale, _newScale, FollowScaleSpeed, Time.deltaTime); break; } } else { this.transform.localScale = _newScale; } }
/// <summary> /// Makes the object follow its target's rotation /// </summary> protected virtual void FollowTargetRotation() { if (Target == null) { return; } if (!FollowRotation) { return; } _newTargetRotation = Target.rotation; if (InterpolateRotation) { switch (FollowRotationMode) { case FollowModes.MMLerp: this.transform.rotation = MMMaths.Lerp(this.transform.rotation, _newTargetRotation, FollowRotationSpeed, Time.deltaTime); break; case FollowModes.RegularLerp: this.transform.rotation = Quaternion.Lerp(this.transform.rotation, _newTargetRotation, Time.deltaTime * FollowRotationSpeed); break; case FollowModes.MMSpring: this.transform.rotation = MMMaths.Lerp(this.transform.rotation, _newTargetRotation, FollowRotationSpeed, Time.deltaTime); break; } } else { this.transform.rotation = _newTargetRotation; } }
/// <summary> /// Follows the target, lerping the position or not based on what's been defined in the inspector /// </summary> protected virtual void FollowTargetPosition() { if (Target == null) { return; } if (!FollowPosition) { return; } _newTargetPosition = Target.position + Offset; if (!FollowPositionX) { _newTargetPosition.x = _initialPosition.x; } if (!FollowPositionY) { _newTargetPosition.y = _initialPosition.y; } if (!FollowPositionZ) { _newTargetPosition.z = _initialPosition.z; } float trueDistance = 0f; _direction = (_newTargetPosition - this.transform.position).normalized; trueDistance = Vector3.Distance(this.transform.position, _newTargetPosition); float interpolatedDistance = trueDistance; if (InterpolatePosition) { switch (FollowPositionMode) { case FollowModes.MMLerp: interpolatedDistance = MMMaths.Lerp(0f, trueDistance, FollowPositionSpeed, Time.deltaTime); interpolatedDistance = ApplyMinMaxDistancing(trueDistance, interpolatedDistance); this.transform.Translate(_direction * interpolatedDistance, Space.World); break; case FollowModes.RegularLerp: interpolatedDistance = Mathf.Lerp(0f, trueDistance, Time.deltaTime * FollowPositionSpeed); interpolatedDistance = ApplyMinMaxDistancing(trueDistance, interpolatedDistance); this.transform.Translate(_direction * interpolatedDistance, Space.World); break; case FollowModes.MMSpring: _newPosition = this.transform.position; MMMaths.Spring(ref _newPosition, _newTargetPosition, ref _velocity, PositionSpringDamping, PositionSpringFrequency, FollowPositionSpeed, Time.deltaTime); if (_localSpace) { this.transform.localPosition = _newPosition; } else { this.transform.position = _newPosition; } break; } } else { interpolatedDistance = ApplyMinMaxDistancing(trueDistance, interpolatedDistance); this.transform.Translate(_direction * interpolatedDistance, Space.World); } if (AnchorToInitialPosition) { if (Vector3.Distance(this.transform.position, _initialPosition) > MaxDistanceToAnchor) { if (_localSpace) { this.transform.localPosition = _initialPosition + Vector3.ClampMagnitude(this.transform.localPosition - _initialPosition, MaxDistanceToAnchor); } else { this.transform.position = _initialPosition + Vector3.ClampMagnitude(this.transform.position - _initialPosition, MaxDistanceToAnchor); } } } }