LoginSignup
7
1

More than 3 years have passed since last update.

非エンジニア向けに簡易的なアニメーションビューア作ってみた

Last updated at Posted at 2020-12-14

この記事はサムザップ #2 Advent Calendar 2020の12/15の記事です。
前日は @Gaku_Ishii さんの【Unity】Androidのファイル作成パフォーマンスはディレクトリにある既存ファイル数の影響を受けるのか?でした。

はじめに

タイトルの通りですが非エンジニア向けに超絶簡易的なアニメーションビューア機能を作ってみました。
本来ならUnityのAnimatorウィンドウとAnimationウィンドウを使えば事足りる機能ですが、本機能は以下の点を重視して手早く作ったものになります。ご留意ください。

  • 非エンジニア向け
  • インスペクタで完結する
  • アニメーションの指定と再生・停止ができる

環境

Unity 2018.4.27f1

demo

こんな感じでLayersとStateをプルダウンから選択して再生・一時停止・再開・停止が可能です
画面収録 2020-12-14 10.46.30.gif
Unityちゃんのアニメーションチェックシーン使っているため若干ややこしい見た目になってますが、インスペクタ内からアニメーションの指定と再生・停止・一時停止・再開ができているのが確認出来るかと思います。
解像度が低くて分かりづらいかもですが、ボタンは左からPlay、Pause、Resume、Stopとなっています。

動画には入っていませんが、AnimationEventsの設定有無も確認できます。

実装

難しいことは一切やっていません。ただただAnimator側の情報を取って表示しているだけです。
細かい制御などは端折って記載しています。

// ...省略...

/// <summary>
/// CustomAnimator参照
/// </summary>
private CustomAnimator _customAnimator;

/// <summary>
/// レイヤー名を格納する配列
/// </summary>
private string[] _layerNames = new string[] { };

/// <summary>
/// ステート名を格納するディクショナリ
/// </summary>
private Dictionary<int, string[]> _stateNamesDict = new Dictionary<int, string[]>();

private int _layerIndex;

private CustomAnimator CustomAnimator
{
    get
    {
        if (_customAnimator == null)
            _customAnimator = target as CustomAnimator;
        return _customAnimator;
    }
}

public override void OnInspectorGUI()
{
    // ...省略...

    EditorGUILayout.LabelField("デバッグ再生");
    _layerIndex = EditorGUILayout.Popup("Layers", _layerIndex, _layerNames);

    var stateNames = _stateNamesDict.ContainsKey(_layerIndex) ? _stateNamesDict[_layerIndex] : new string[] { };
    _stateIndex = EditorGUILayout.Popup("States", _stateIndex, stateNames);
    _stateName = stateNames.Length > 0 ? stateNames[_stateIndex] : string.Empty;

    using (new EditorGUILayout.HorizontalScope())
    {
        if (GUILayout.Button("Play"))
        {
            var fullPathHash = Animator.StringToHash(string.Join(".", _animator.GetLayerName(_layerIndex), _stateName));
            CustomAnimator.Play(fullPathHash, _layerIndex, _normalizedTime, () =>
            {
                Debug.Log("Complete");
            });
        }
        if (GUILayout.Button("Pause"))
        {
            CustomAnimator.Pause();
        }
        if (GUILayout.Button("Resume"))
        {
            CustomAnimator.Resume();
        }
        if (GUILayout.Button("Stop"))
        {
            CustomAnimator.Stop();
        }
    }

    // ...省略...
}

// ...省略...

実行時にAnimatorControllerのLayersとStatesの拾い方がわからなくてググりました。
以下方法で拾えることがわかって勉強になりました。

// UnityEditorのAnimatorControllerでキャスト
var controller = _animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
for (var i = 0; i < controller.layers.Length; i++)
{
    var layer = controller.layers[i];
    Debug.Log(layer.name); // レイヤー名

    var states = layer.stateMachine.states;
    foreach (var state in states)
    {
        Debug.Log(state.state.name); // ステート名
    }
}             

以上になります。
明日は @IwakamiYuki さんの記事です。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1