読者です 読者をやめる 読者になる 読者になる

渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きく慣れるように。。。 ※所属団体とは一切関係がありません

Unity AnimationClipに設定されたAnimationEventを取得する方法


f:id:esakun:20150730215258g:plain

AnimationEventはプログラマーとアーティストの作業分担に役立つ機能ですが、AnimationEventまわりでエラーが起きた時に、正しくEventが設定されているか、バリデーションをかけたい時があると思います。

記事にするほどでもないほど、とても簡単に実装可能なのですが、 今回非常に遠回りをしちゃったので記事化しています。

まずは遠回りverから

.animファイル自体を解析して取得する方法です。

適当にAnimationEventを設定したAnimationClip(Test.anim)を用意し、テキストエディタで開きます。
シリアライズされたオブジェクトはYAML形式のテキストになります。

するとテキスト終盤に以下のようなm_Eventsという配列ブロックが出てきます。
※これがシリアライズされたAnimationEventです。

%YAML 1.1
~~~~~~~ 略 ~~~~~~~~
m_Events:
- time: 0.41666666
  functionName: TestFunc
  data: 
  objectReferenceParameter: {fileID: 0}
  floatParameter: 0
  intParameter: 0
  messageOptions: 0

m_Eventsの中身を解析すればAnimationEventの設定有無をチェックできます。

これをどうやって取得するか、解説していきます。

Test.animをシリアライズオブジェクトにします

シリアライズオブジェクトにすることで、APIとして公開されているものではない、シリアライズ状態のオブジェクトを取得する事ができるようになります。

// シリアライズオブジェクトに変換
var obj = new SerializedObject(anim);
// シリアライズ状態のAnimationEvent(m_Events)の配列プロパティを取得
var events = obj.FindProperty("m_Events");
foreach (SerializedProperty e in events) {
    Debug.Log(e.FindPropertyRelative("functionName").stringValue);
}

上記のようにFindProperty関数を使用して地道に各プロパティを参照していきます。

では近道ver

なんとeventsプロパティで簡単にAnimationEvent配列を取得できます。
関数名が設定されていない場合は空文字が返却されるので、そこでバリデーションをかければOKかと。

foreach (var e in anim.events) {
    Debug.Log(e.functionName);
}

うむ、簡単 & シンプル。

まとめ

APIとして提供されていることに早く気付けばよかったわけですが、シリアライズオブジェクトにすれば(Unity.Objectであれば)、どんなプロパティも解析できるということが分かったことは大きな収穫だったかなと思います。

この方法を使えば、隠された機能をゴニョゴニョすることが可能になるため、とても便利なEditor拡張作れるようになるのではないでしょうか。

注意1

また、今回の.animファイルをテキスト表示させるためには、 Edit > Project Settings > Editor > Asset Serialization ModeForce Textにする必要があります。

注意2

シリアライズされたテキスト内容はUnityのバージョンアップによって変更される可能性があるということを留意すべきかと思います。

参考文献

https://s.booth.pm/392f794e-f56e-4207-981e-00635fca8639/i/128404/424aad97-455e-4bcb-be7a-5172976e0026.jpg

安藤さんの『Unityエディター拡張』
https://kyusyukeigo.booth.pm/items/128404

1000円でこの内容はコスパ良すぎです。