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();
}
}
}