[MaxScript] 3dsmax でアニメーションしているコントローラを全部回収する

3dsmax でそのオブジェクトのどこかにキーが打たれているかどうか知りたい。簡単ですね。オブジェクトを選択してキーフィルタを「すべて」にし、タイムラインにキーが表示されればどこかにキーが打たれている。

さて、これをスクリプトからやり、ついでに、どこにキーが打たれているのかも取得したい、というのが今回のトピックです。例によって細かく作っていくので結果だけ欲しい人は最終的なコードまでジャンプしてください。

設計

最終的にオブジェクトを渡したらアニメーションしているコントローラを全部格納した配列が戻ってくる、という風にしたい。

ここで面倒くさそうなのは、3dsmax はほとんどすべてのコントローラがアニメーション可能(Animatable)で、さらにサブアニメーション(SubAnim)という仕組みで階層構造になっている、という点です。

さらに、モディファイヤを乗せてモディファイヤのアトリビュートにキーを打つこともできる。

そしてオブジェクトがどのような構造になっているかはオブジェクトによる、というわけで、再帰をうまいこと使ってなんとかしましょう。だいたいの方針は以下のようにします。

  • 最終的にオブジェクト(ノード)を渡してコントローラのリストを得る
  • コントローラを渡すとその下についているサブアニメーションを全部確認して、キーのあるものだけを回収する関数を作る
  • モディファイヤを渡すとそのサブアニメーションを全部確認して、キーのあるものだけを回収する関数を作る

最終的に使う関数の骨組

こんな感じ。最終目標から中の処理を考えて、1つずつ動作をイメージしていくのがわかりやすいと(僕は)思います。

オブジェクトが直接持っているコントローラからサブアニメーションを回収する

モディファイヤのことはひとまず置いておき、オブジェクトが直接持っているサブアニメーションについて考えます。代表的なものはトランスフォームコントローラですが、オブジェクトの種別によって持っているコントローラの種類は異なり、それによりサブアニメーションの種類や数も異なります。どんなものにでも対応できるような再帰関数を考えましょう。

モディファイヤのサブアニメーションを回収する

モディファイヤの場合はモディファイヤのサブアニメーションコントローラを回収し、そのコントローラに対して上で作ったgetAnimatedCtrls を実行します。

最初に骨組だけ作った関数を完成させる

これを複数のオブジェクトに対して実行する

あとはこれを任意のオブジェクトに対して実行するだけ。選択したもの全部、シーン内のオブジェクト全部、等に対して実行する場合は以下のように取得した配列をjoin で連結すれば1つの配列にすべて格納できる。

もちろんオブジェクトごとに得た配列を配列にする、といったことも可能。

最終的なコード

よかったらお使いくださいませ。