こんにちは、Unityエンジニアのオオバです。

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

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

👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

まずは遠回り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のバージョンアップによって変更される可能性があるということを留意すべきかと思います。

オススメ記事
検証環境