namespace Zinnia.Tracking.Follow.Modifier.Property
{
using UnityEngine;
using UnityEngine.Events;
using Zinnia.Extension;
public abstract class SmoothedRestrictableTransformPropertyModifier : RestrictableTransformPropertyModifier
{
[Header("Smoothing Settings")]
[Tooltip("The tolereance to consider the source and target property equal.")]
[SerializeField]
private float equalityTolerance = float.Epsilon;
///
/// The tolereance to consider the source and target property equal.
///
public float EqualityTolerance
{
get
{
return equalityTolerance;
}
set
{
equalityTolerance = value;
}
}
[Tooltip("The approximate duration of transition for the smoothing operation.")]
[SerializeField]
private float transitionDuration = 0f;
///
/// The approximate duration of transition for the smoothing operation.
///
public float TransitionDuration
{
get
{
return transitionDuration;
}
set
{
transitionDuration = value;
}
}
[Tooltip("The maximum speed the object can move between the smoothed distances.")]
[SerializeField]
private float maxSpeed = Mathf.Infinity;
///
/// The maximum speed the object can move between the smoothed distances.
///
public float MaxSpeed
{
get
{
return maxSpeed;
}
set
{
maxSpeed = value;
}
}
[Header("Smoothing Events")]
///
/// Emitted when the smoothing transition has completed.
///
public UnityEvent Transitioned = new UnityEvent();
///
/// The reference to the output velocity.
///
public Vector3 Velocity => velocity;
private Vector3 velocity;
///
/// The reference to the output angulaer velocity.
///
public Quaternion AngularVelocity => angularVelocity;
private Quaternion angularVelocity;
///
/// Whether the velocity is currently being smoothed.
///
protected bool isVelocitySmoothing;
///
/// Whether the angular velocity is currently being smoothed.
///
protected bool isAngularVelocitySmoothing;
///
/// Gradually changes a towards a desired goal over time.
///
/// The current position.
/// The position we are trying to reach.
/// The smoothed value.
protected virtual Vector3 Smooth(Vector3 current, Vector3 final)
{
if (TransitionDuration.ApproxEquals(0f) || current.ApproxEquals(final, EqualityTolerance))
{
if (isVelocitySmoothing)
{
Transitioned?.Invoke();
}
isVelocitySmoothing = false;
return final;
}
isVelocitySmoothing = true;
return Vector3.SmoothDamp(current, final, ref velocity, TransitionDuration, MaxSpeed, Time.deltaTime);
}
///
/// Gradually changes a towards a desired goal over time.
///
/// The current position.
/// The position we are trying to reach.
/// The smoothed value.
protected virtual Quaternion Smooth(Quaternion current, Quaternion final)
{
if (TransitionDuration.ApproxEquals(0f) || current.ApproxEquals(final, EqualityTolerance))
{
if (isAngularVelocitySmoothing)
{
Transitioned?.Invoke();
}
isAngularVelocitySmoothing = false;
return final;
}
isAngularVelocitySmoothing = true;
return QuaternionExtensions.SmoothDamp(current, final, ref angularVelocity, TransitionDuration);
}
}
}