namespace Zinnia.Tracking.Velocity { using UnityEngine; using Zinnia.Extension; using Zinnia.Process; /// /// Applies artificial velocities to the by changing the properties. /// public class ArtificialVelocityApplierProcess : MonoBehaviour, IProcessable { [Tooltip("The object to apply the artificial velocities to.")] [SerializeField] private GameObject target; /// /// The object to apply the artificial velocities to. /// public GameObject Target { get { return target; } set { target = value; } } [Tooltip("The velocity to apply.")] [SerializeField] private Vector3 velocity; /// /// The velocity to apply. /// public Vector3 Velocity { get { return velocity; } set { velocity = value; } } [Tooltip("The angular velocity to apply.")] [SerializeField] private Vector3 angularVelocity; /// /// The angular velocity to apply. /// public Vector3 AngularVelocity { get { return angularVelocity; } set { angularVelocity = value; } } [Tooltip("The drag to apply to reduce the directional velocity over time and to slow down Target.")] [SerializeField] private float drag = 1f; /// /// The drag to apply to reduce the directional velocity over time and to slow down . /// public float Drag { get { return drag; } set { drag = value; } } [Tooltip("The angular drag to apply to reduce the rotational velocity over time and to slow down Target.")] [SerializeField] private float angularDrag = 0.5f; /// /// The angular drag to apply to reduce the rotational velocity over time and to slow down . /// public float AngularDrag { get { return angularDrag; } set { angularDrag = value; } } [Tooltip("The tolerance the velocity can be within zero to be considered nil.")] [SerializeField] private float nilVelocityTolerance = 0.001f; /// /// The tolerance the velocity can be within zero to be considered nil. /// public float NilVelocityTolerance { get { return nilVelocityTolerance; } set { nilVelocityTolerance = value; } } [Tooltip("The tolerance the angular velocity can be within zero to be considered nil.")] [SerializeField] private float nilAngularVelocityTolerance = 0.001f; /// /// The tolerance the angular velocity can be within zero to be considered nil. /// public float NilAngularVelocityTolerance { get { return nilAngularVelocityTolerance; } set { nilAngularVelocityTolerance = value; } } /// /// Determine if we can process. /// protected bool canProcess = false; /// /// Clears . /// public virtual void ClearTarget() { if (!this.IsValidState()) { return; } Target = default; } /// /// Sets the x value. /// /// The value to set to. public virtual void SetVelocityX(float value) { Velocity = new Vector3(value, Velocity.y, Velocity.z); } /// /// Sets the y value. /// /// The value to set to. public virtual void SetVelocityY(float value) { Velocity = new Vector3(Velocity.x, value, Velocity.z); } /// /// Sets the z value. /// /// The value to set to. public virtual void SetVelocityZ(float value) { Velocity = new Vector3(Velocity.x, Velocity.y, value); } /// /// Increments the by the given value. /// /// The value to increment by. public virtual void IncrementVelocity(Vector3 value) { Velocity += value; } /// /// Reset to . /// public virtual void ClearVelocity() { Velocity = Vector3.zero; } /// /// Sets the x value. /// /// The value to set to. public virtual void SetAngularVelocityX(float value) { AngularVelocity = new Vector3(value, AngularVelocity.y, AngularVelocity.z); } /// /// Sets the y value. /// /// The value to set to. public virtual void SetAngularVelocityY(float value) { AngularVelocity = new Vector3(AngularVelocity.x, value, AngularVelocity.z); } /// /// Sets the z value. /// /// The value to set to. public virtual void SetAngularVelocityZ(float value) { AngularVelocity = new Vector3(AngularVelocity.x, AngularVelocity.y, value); } /// /// Increments the by the given value. /// /// The value to increment by. public virtual void IncrementAngularVelocity(Vector3 value) { AngularVelocity += value; } /// /// Reset to . /// public virtual void ClearAngularVelocity() { AngularVelocity = Vector3.zero; } /// /// Applies the velocity data to the . /// public virtual void Apply() { if (!this.IsValidState()) { return; } canProcess = true; } /// public virtual void Process() { if (!canProcess) { return; } if (!Velocity.ApproxEquals(Vector3.zero, NilVelocityTolerance) || !AngularVelocity.ApproxEquals(Vector3.zero, NilAngularVelocityTolerance)) { float deltaTime = Time.inFixedTimeStep ? Time.fixedDeltaTime : Time.deltaTime; Velocity = Vector3.Lerp(Velocity, Vector3.zero, Drag * deltaTime); AngularVelocity = Vector3.Lerp(AngularVelocity, Vector3.zero, AngularDrag * deltaTime); Target.transform.localRotation *= Quaternion.Euler(AngularVelocity); Target.transform.localPosition += Velocity * deltaTime; } else { Velocity = Vector3.zero; AngularVelocity = Vector3.zero; canProcess = false; } } /// /// Cancels the . /// public virtual void CancelDeceleration() { canProcess = false; } protected virtual void OnDisable() { CancelDeceleration(); } } }