うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】UnityEditor 上で Animation を再生するための便利クラス

UnityEditor 上で Animation の再生をするのはちょっと面倒なので、
手軽にできるようにクラスを作成してみました

コード

[Serializable]
public class EditorPlayAnimation
{
    [SerializeField]
    private Animator _animator;
    [SerializeField]
    private List<AnimationClipData> _clips = new List<AnimationClipData>();
 
    private DateTime _targetTime;
 
    public Animator Animator => _animator;
    public IEnumerable<AnimationClipData> Clips => _clips;
 
    [Serializable]
    public class AnimationClipData
    {
        public int Layer;
        public string LayerName;
        public string Name;
        public float Length;
    }
 
    public EditorAnimation(Animator animator)
    {
        if (animator == null)
            return;

        _animator = animator;

        var ac = _animator.runtimeAnimatorController as AnimatorController;
        _clips = new List<AnimationClipData>();
        var index = 0;
        foreach (var layer in ac.layers)
        {
            foreach (var state in layer.stateMachine.states)
            {
                var clip = state.state.motion as AnimationClip;
                _clips.Add(new AnimationClipData
                {
                    Layer = index,
                    LayerName = layer.name,
                    Name = state.state.name,
                    Length = clip != null ? clip.length : 0f,
                });
            }

            index++;
        }
    }
 
    public void PlayAnimation(AnimationClipData data)
    {
        if (_animator == null)
            return;

        _animator.Play(data.Name, data.Layer);
        _animator.speed = 1f;
        _targetTime = DateTime.Now.AddSeconds(data.Length);

        EditorApplication.update -= UpdateAnimation;
        EditorApplication.update += UpdateAnimation;
    }
 
    public void StopAnimation()
    {
        EditorApplication.update -= UpdateAnimation;
    }
 
    private void UpdateAnimation()
    {
        if (_targetTime < DateTime.Now)
        {
            EditorApplication.update -= UpdateAnimation;
            return;
        }

        _animator.Update(Time.deltaTime);
    }
}

サンプル

AnimatorEditorPlayAnimation 生成時に渡して よしなにするだけで Animator を再生できるようになります

f:id:hacchi_man:20201207012949p:plain:w400

var playAnimation = new EditorPlayAnimation(AssetDatabase.LoadAssetAtPath<Animator>("Path"));
foreach (var clip in playAnimation.Clips)
{
    if (GUILayout.Button(clip.Name))
    {
        // 再生
        playAnimation.PlayAnimation(clip);
    }
}
 
// 停止
if (GUILayout.Button("Stop"))
{
    playAnimation.StopAnimation();
}