// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 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
{
/************************************************************************************************************************/
/// An that creates a .
public interface ITransition : ITransition { }
/************************************************************************************************************************/
#region Fields and Properties
/************************************************************************************************************************/
/// The which this state plays.
private AnimationClip _Clip;
/// The which this state plays.
public override AnimationClip Clip
{
get => _Clip;
set
{
Validate.AssertNotLegacy(value);
ChangeMainObject(ref _Clip, value);
}
}
/// The which this state plays.
public override Object MainObject
{
get => _Clip;
set => Clip = (AnimationClip)value;
}
/************************************************************************************************************************/
/// The .
public override float Length => _Clip.length;
/************************************************************************************************************************/
/// The .
public override bool IsLooping => _Clip.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.AssertNotLegacy(clip);
_Clip = clip;
}
/************************************************************************************************************************/
/// Creates and assigns the managed by this node.
protected override void CreatePlayable(out Playable playable)
{
playable = AnimationClipPlayable.Create(Root._Graph, _Clip);
}
/************************************************************************************************************************/
///
public override void Destroy()
{
_Clip = null;
base.Destroy();
}
/************************************************************************************************************************/
///
public override AnimancerState Clone(AnimancerPlayable root)
{
var clone = new ClipState(_Clip);
clone.SetNewCloneRoot(root);
((ICopyable)clone).CopyFrom(this);
return clone;
}
/************************************************************************************************************************/
#endregion
/************************************************************************************************************************/
#region Inspector
#if UNITY_EDITOR
/************************************************************************************************************************/
/// [Editor-Only] Returns a for this state.
protected internal override Editor.IAnimancerNodeDrawer CreateDrawer() => new Drawer(this);
/************************************************************************************************************************/
///
public class Drawer : Editor.AnimancerStateDrawer
{
/************************************************************************************************************************/
/// Creates a new to manage the Inspector GUI for the `state`.
public Drawer(ClipState state) : base(state) { }
/************************************************************************************************************************/
///
protected override void AddContextMenuFunctions(UnityEditor.GenericMenu menu)
{
menu.AddDisabledItem(new GUIContent(
$"{DetailsPrefix}Animation Type: {Editor.AnimationBindings.GetAnimationType(Target._Clip)}"));
base.AddContextMenuFunctions(menu);
Editor.AnimancerEditorUtilities.AddContextMenuIK(menu, Target);
}
/************************************************************************************************************************/
}
/************************************************************************************************************************/
#endif
#endregion
/************************************************************************************************************************/
}
}