namespace Zinnia.Tracking.Follow.Modifier.Property.Position { using UnityEngine; using Zinnia.Extension; /// /// Updates the velocity by moving towards a given source. /// public class RigidbodyVelocity : DivergablePropertyModifier { #region Velocity Settings [Header("Velocity Settings")] [Tooltip("The maximum squared magnitude of velocity that can be applied to the source.")] [SerializeField] private float velocityLimit = float.PositiveInfinity; /// /// The maximum squared magnitude of velocity that can be applied to the source. /// public float VelocityLimit { get { return velocityLimit; } set { velocityLimit = value; } } [Tooltip("The maximum difference in distance to the tracked position.")] [SerializeField] private float maxDistanceDelta = 10f; /// /// The maximum difference in distance to the tracked position. /// public float MaxDistanceDelta { get { return maxDistanceDelta; } set { maxDistanceDelta = value; } } #endregion /// /// A cached version of the target . /// protected Rigidbody cachedTargetRigidbody; /// /// A cached version of the target. /// protected GameObject cachedTarget; /// /// Modifies the target velocity to move towards the given source. /// /// The source to utilize in the modification. /// The target to modify. /// The offset of the target against the source when modifying. protected override void DoModify(GameObject source, GameObject target, GameObject offset = null) { cachedTargetRigidbody = cachedTargetRigidbody == null || target != cachedTarget ? target.TryGetComponent(true) : cachedTargetRigidbody; cachedTarget = target; Vector3 positionDelta = source.transform.position - (offset != null ? offset.transform.position : target.transform.position); float deltaTime = Time.inFixedTimeStep ? Time.fixedDeltaTime : Time.deltaTime; Vector3 velocityTarget = positionDelta / deltaTime; Vector3 calculatedVelocity = Vector3.MoveTowards(cachedTargetRigidbody.velocity, velocityTarget, MaxDistanceDelta / deltaTime); if (!cachedTargetRigidbody.isKinematic && calculatedVelocity.sqrMagnitude < VelocityLimit) { cachedTargetRigidbody.velocity = calculatedVelocity; } base.DoModify(source, target, offset); } /// /// Gets the source and target positions to check divergence against. /// /// The source to check against. /// The target to check with. /// Any offset applied to the target. /// The source position. /// The target position. protected override void GetCheckPoints(GameObject source, GameObject target, GameObject offset, out Vector3 a, out Vector3 b) { a = source.transform.position; b = target.transform.position; if (offset != null) { a = source.transform.position - (offset.transform.position - target.transform.position); } } } }