// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik // using System; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; using Object = UnityEngine.Object; namespace Animancer { /// An which plays an . /// /// Documentation: /// /// States /// /// https://kybernetik.com.au/animancer/api/Animancer/ClipState /// public class ClipState : AnimancerState { /************************************************************************************************************************/ #region Fields and Properties /************************************************************************************************************************/ private AnimationClip _Clip; /// The which this state plays. public override AnimationClip Clip { get => _Clip; set { Validate.AssertAnimationClip(value, true, $"set {nameof(ClipState)}.{nameof(Clip)}"); if (ChangeMainObject(ref _Clip, value)) { _Length = value.length; var isLooping = value.isLooping; if (_IsLooping != isLooping) { _IsLooping = isLooping; OnIsLoopingChangedRecursive(isLooping); } } } } /// The which this state plays. public override Object MainObject { get => _Clip; set => Clip = (AnimationClip)value; } #if UNITY_EDITOR /// public override Type MainObjectType => typeof(AnimationClip); #endif /************************************************************************************************************************/ private float _Length; /// The . public override float Length => _Length; /************************************************************************************************************************/ private bool _IsLooping; /// The . public override bool IsLooping => _IsLooping; /************************************************************************************************************************/ /// public override void GetEventDispatchInfo( out float length, out float normalizedTime, out bool isLooping) { length = _Length; normalizedTime = length != 0 ? Time / length : 0; isLooping = _IsLooping; } /************************************************************************************************************************/ /// public override Vector3 AverageVelocity => _Clip.averageSpeed; /************************************************************************************************************************/ #region Inverse Kinematics /************************************************************************************************************************/ /// public override bool ApplyAnimatorIK { get => _Playable.IsValid() && ((AnimationClipPlayable)_Playable).GetApplyPlayableIK(); set { Validate.AssertPlayable(this); ((AnimationClipPlayable)_Playable).SetApplyPlayableIK(value); } } /************************************************************************************************************************/ /// public override bool ApplyFootIK { get => _Playable.IsValid() && ((AnimationClipPlayable)_Playable).GetApplyFootIK(); set { Validate.AssertPlayable(this); ((AnimationClipPlayable)_Playable).SetApplyFootIK(value); } } /************************************************************************************************************************/ #endregion /************************************************************************************************************************/ #endregion /************************************************************************************************************************/ #region Methods /************************************************************************************************************************/ /// Creates a new and sets its . /// The `clip` is null. public ClipState(AnimationClip clip) { Validate.AssertAnimationClip(clip, true, $"create {nameof(ClipState)}"); _Clip = clip; _Length = clip.length; _IsLooping = clip.isLooping; } /************************************************************************************************************************/ /// Creates and assigns the managed by this node. protected override void CreatePlayable(out Playable playable) { playable = AnimationClipPlayable.Create(Graph._PlayableGraph, _Clip); } /************************************************************************************************************************/ /// public override void RecreatePlayable() { var playable = (AnimationClipPlayable)_Playable; var footIK = playable.GetApplyFootIK(); var playableIK = playable.GetApplyPlayableIK(); base.RecreatePlayable(); playable = (AnimationClipPlayable)_Playable; playable.SetApplyFootIK(footIK); playable.SetApplyPlayableIK(playableIK); } /************************************************************************************************************************/ /// public override void Destroy() { _Clip = null; base.Destroy(); } /************************************************************************************************************************/ /// public override AnimancerState Clone(CloneContext context) { var clip = context.GetCloneOrOriginal(_Clip); var clone = new ClipState(clip); clone.CopyFrom(this, context); return clone; } /************************************************************************************************************************/ #endregion /************************************************************************************************************************/ } }