using System;
using UnityEngine.Serialization;
namespace UnityEngine.Animations.Rigging
{
///
/// The OverrideRigLayer is used to override constraints normally evaluated by
/// a specified Rig component.
///
[Serializable]
public class OverrideRigLayer : IRigLayer
{
[SerializeField] [FormerlySerializedAs("rig")] private Rig m_Rig;
[SerializeField] [FormerlySerializedAs("active")] private bool m_Active = true;
private IRigConstraint[] m_Constraints;
private IAnimationJob[] m_Jobs;
/// The Rig associated to the OverrideRigLayer
public Rig rig { get => m_Rig; private set => m_Rig = value; }
/// The active state. True if the OverrideRigLayer is active, false otherwise.
public bool active { get => m_Active; set => m_Active = value; }
/// The OverrideRigLayer name.
public string name { get => (rig != null ? rig.gameObject.name : "no-name"); }
/// The list of constraints associated with the OverrideRigLayer.
public IRigConstraint[] constraints { get => isInitialized ? m_Constraints : null; }
/// The list of jobs built from constraints associated with the OverrideRigLayer.
public IAnimationJob[] jobs { get => isInitialized ? m_Jobs : null; }
/// Returns true if OverrideRigLayer was initialized or false otherwise.
///
public bool isInitialized { get; private set; }
///
/// Constructor.
///
/// The rig represented by this override rig layer.
/// The constraints that override those of the rig.
/// The active state of the override rig layer.
public OverrideRigLayer(Rig rig, IRigConstraint[] constraints, bool active = true)
{
this.rig = rig;
this.active = active;
m_Constraints = constraints;
}
///
/// Initializes the OverrideRigLayer. This will create animation jobs using
/// the rig constraints provided to the OverrideRigLayer.
///
/// The Animator used to animate the RigLayer constraints.
/// True if RigLayer was initialized properly, false otherwise.
public bool Initialize(Animator animator)
{
if (isInitialized)
return true;
if (rig == null)
return false;
if (m_Constraints == null || m_Constraints.Length == 0)
return false;
m_Jobs = new IAnimationJob[m_Constraints.Length];
for (int i = 0; i < m_Constraints.Length; ++i)
{
m_Jobs[i] = m_Constraints[i].CreateJob(animator);
}
return isInitialized = true;
}
///
/// Updates the OverrideRigLayer jobs. This is called during the Update loop before
/// the Animator evaluates the PlayableGraph.
///
public void Update()
{
if (!isInitialized)
return;
for (int i = 0; i < m_Constraints.Length; ++i)
{
m_Constraints[i].UpdateJob(m_Jobs[i]);
}
}
///
/// Resets the OverrideRigLayer. This will destroy the animation jobs and
/// free up memory.
///
public void Reset()
{
if (!isInitialized)
return;
for (int i = 0, count = m_Constraints.Length; i < count; ++i)
{
m_Constraints[i].DestroyJob(m_Jobs[i]);
}
m_Constraints = null;
m_Jobs = null;
isInitialized = false;
}
///
/// Queries whether the OverrideRigLayer is valid.
///
/// True if OverrideRigLayer is valid, false otherwise.
public bool IsValid() => rig != null && isInitialized;
}
}