【Unity】Animatorのプロパティやステートへのアクセスを容易にするエディタ拡張
ふと思いついて、Animatorのステートやパラメータに定数でアクセスする為のコードを自動生成するエディター拡張を作成しました。
導入方法は
ファイルをインポートするだけです。
この機能を使用するモチベーション
Animatorがインポートされた際にAnimatorの持つステートやパラメータへアクセスする為のハッシュ値を持つクラスを作成します。パラメータへのアクセスにはプロパティ・トリガーへのアクセスはメソッドを使うようになり、typoの防止やアクセスが楽になります。
Animaotrを使用
animator.SetFloat ("FloatParameter", 32);
var result = animator.GetFloat ("FloatParameter");
自動生成コードの使用
controller.FloatParameter = 32;
var result = controller.FloatParameter;
もう一つのモチベーションはハッシュ値の使用です。Unity - マニュアル: パフォーマンスと最適化 にも書かれている通り、Animatorの最適化要因の一つとしてハッシュ値の利用があります。このハッシュ値ですが実行時に文字列から生成するのも馬鹿らしいので、定数として格納しクラスから取得する形に変更します。
ランダムにメモリを格納するリストを含むクラスはGCが遅くなる傾向があるらしく、文字列のようなオブジェクトをクラスに文字列を含める気にならなかったのもモチベーションの一つです。
[Unite 2015 TOKYO]Unity パフォーマンス・チューニング on Vimeo
機能の内容
ベースはImporterのエディタ拡張です。AnimationControllerのインポートが行われると自動的に無慈悲にコードを作成します。
コードは、パラメータへのアクセスはプロパティ、ステートへのアクセスは定数で格納されます。深い階層を持つ場合、「.」の部分が「_」に変換されます。
作成したコードは、Animatorと同じパスに作成されます。その後もAnimatorの位置に従って常に動き、Animatorが削除されるとファイルも削除されます。つまりAnimationControllerに対して1:1でコードが作成されます。
クラス名もAnimationControllerと同じ名前になるので、名前の重複には注意が必要です。また、同じフォルダにコードが無かった場合プロジェクトを探して取得する関係上、同一AnimatorControllerがある場合は注意が必要です。
なおAnimationControllerの更新タイミングはAnimationControllerを更新したタイミングではなく「メタデータが更新されるタイミング」です。つまりProjectのSave時です。
Unity開発者が複数人で開発を進める上で覚えておくと幸せになる9つの事 - テラシュールブログ
コンパイル済みコードではなく単純なコードを出力してる理由は、DOMが面倒だったのと、プロジェクト内で使用していないアセットを削除するエディタ拡張を試作中 - テラシュールブログがコンパイル済みコードを取り除けないという、凄く個人的な理由です。下の図ではSampleController.csはDemo2シーンでしか使ってないので、Demo2が含まれないプロジェクトでは削除対象になっています。
サンプル
tsubaki/Unity-AnimatorAccessHelper · GitHub
自動生成コードからキャラクターをアクセスするサンプル(Demo)と、単純にAnimatorのパラメータを操作するサンプル(Demo2)があります。
Demoに使われているAssetStoreのファイル群は別途インポートする必要があります。「A$」ボタンを押すとリンクへ飛ぶので、あとは手動でインポートします。
デモが上手く動作しない場合はUnityエディタを再起動すると上手くいきます。また、エラーが出てウィンドウの中身が空になった場合もエディタを再起動すると復旧します。
【Unity】指定のアセットがプロジェクト内に存在しない場合、不足アセット一覧とパッケージへのリンクを表示してくれる効果が発動するアセットを作成した - テラシュールブログ
関連
この機能は簡単にアクセスできる反面、正しいAnimationControllerを設定しないと動作しない・AnimationControllerの数が増えると管理が面倒になる等があるので、コガネブログさんのAnimatorStateNameで単に定数管理し基本APIで操作するのは、理に適ってます。