namespace UnityEngine.Animations.Rigging
{
///
/// This is the base class for rig constraints.
/// Inherit from this class to implement custom constraints.
///
/// The constraint job
/// The constraint data
/// The constraint job binder
public class RigConstraint : MonoBehaviour, IRigConstraint
where TJob : struct, IWeightedAnimationJob
where TData : struct, IAnimationJobData
where TBinder : AnimationJobBinder, new()
{
///
/// The constraint weight parameter.
///
[SerializeField, Range(0f, 1f)]
protected float m_Weight = 1f;
///
/// The constraint data.
///
[SerializeField, ExpandChildren]
protected TData m_Data;
static readonly TBinder s_Binder = new TBinder();
///
/// Resets constraint data to default values.
///
public void Reset()
{
m_Weight = 1f;
m_Data.SetDefaultValues();
}
///
/// Retrieves the constraint valid state.
///
/// Returns true if constraint data can be successfully evaluated. Returns false otherwise.
public bool IsValid() => m_Data.IsValid();
///
/// This function is called when the script is loaded or a value is changed in the Inspector (Called in the editor only).
/// You can use this to ensure that when you modify data in an editor, that data stays within a certain range.
///
protected virtual void OnValidate() => m_Weight = Mathf.Clamp01(m_Weight);
///
/// The data container for the constraint.
///
public ref TData data => ref m_Data;
///
/// The constraint weight. This is a value in between 0 and 1.
///
public float weight { get => m_Weight; set => m_Weight = Mathf.Clamp01(value); }
///
/// Creates the animation job for this constraint.
///
/// The animated hierarchy Animator component
/// Returns the newly instantiated job.
public IAnimationJob CreateJob(Animator animator)
{
TJob job = s_Binder.Create(animator, ref m_Data, this);
// Bind constraint job weight property
job.jobWeight = FloatProperty.BindCustom(
animator,
ConstraintsUtils.ConstructCustomPropertyName(this, ConstraintProperties.s_Weight)
);
return job;
}
///
/// Frees the specified job memory.
///
/// The job to destroy.
public void DestroyJob(IAnimationJob job) => s_Binder.Destroy((TJob)job);
///
/// Updates the specified job data.
///
/// The job to update.
public void UpdateJob(IAnimationJob job) => s_Binder.Update((TJob)job, ref m_Data);
///
/// The job binder for the constraint.
///
IAnimationJobBinder IRigConstraint.binder => s_Binder;
///
/// The data container for the constraint.
///
IAnimationJobData IRigConstraint.data => m_Data;
///
/// The component for the constraint.
///
Component IRigConstraint.component => (Component)this;
}
}