なぜ、アニメーション ブループリントにすべきなのか?
「アニメーション ブループリント」という語は、単なるブループリントという語よりも何やら恐ろしげに聞こえます。ブループリントは楽しかったけれど、今度のアニメーション ブループリントは、ブループリントとは違った働きをしそうです。そこで私はこれについて説明しようと思い立ちました。
まず、アンリアル・エンジンでアニメーションがどのように再生されるかということについて考えてみましょう。
スケルタルメッシュ コンポーネント上でアニメーションを再生するには 2 通りの方法があります。すでにご存知かもしれませんが、スケルタルメッシュ コンポーネントには、ボーンの階層が含まれています。これには、アニメーションがその上で再生されることになる、スキニングされたメッシュがともないます。アニメーションをレベル内にドラッグすると、スケルタルメッシュ コンポーネントを含むスケルタルメッシュ アクタが作成されるとともに、自動的に基本となる情報がセットアップされます。
アクタを詳細パネルで選択する時、特に、データのこのセクションに注目してください。
あらゆるスケルタルメッシュ コンポーネントには、Animation Mode の設定項目があります。先に述べたように、アニメーションを再生する方法が 2 つあるので、そこから 1 つを選択します。
- Use Animation Asset (アニメーション アセットを使用する): この方式が適用されるのは、アニメーション シーケンスまたはアニメーション コンポジットに対してのみです。これは所定のタイムラインに沿って有効なポーズを作成できる 1 つのアセットです。
- Use Animation Blueprint (アニメーション ブループリントを使用する): このモードを使用すると、アニメーション ブループリントを再生できるようになります。
最初の方式は簡単に思われますが、2 つ目の方式は説明が必要です。
2 つ目の方式は、まさにアニメーション ブループリントを使用する (Use Animation Blueprint) ためのものです。
アニメーション ブループリントをコンテンツ ブラウザからレベル ビューポートにドラッグすると、下図のようにアニメーション ブループリントがセットアップされた状態でスケルタルメッシュ アクタが作成されます。(アニメーション シーケンスをレベル ビューポートにドラッグする場合の上記動作と同様です。)
1 個のアニメーションを再生する場合は単純ですが、複数のアニメーションを再生し、さまざまな条件に基いてそれらをブレンドする (異なるブレンドのアニメーションを再生する) 場合はやや複雑になるので、アニメーション ブループリントが役に立ちます。パラメータとか現在の時間といった現在の状態に基いて機能することができるのです。
アニメーション ブループリントを作成すると、2 つのグラフができることになります。それらについては次のリンク先でとても分かりやすく解説されています。
https://docs.unrealengine.com/latest/INT/Engine/Animation/AnimBlueprints/index.html
2 つのグラフは、EventGraph (イベントグラフ) と AnimGraph (アニメーション グラフ) です。
EventGraph は AnimInstance のためのブループリントと同じです。変数をセットしたり、関数を呼び出したりすることができ、トリガーのためのイベントがあります。各ノードを呼び出すことによって実行する動作のシーケンスがあります。
AnimGraph の機能は若干異なります。これはアニメーションがブレンドされる場所です。動作のシーケンスというよりも、ツリー構造として考えることができます。各ノードにはそれ独自の処理手順があり、結果としてポーズが作成されます。
まず、EventGraph の例をご覧ください。
ブループリントを理解されていれば、これはとても分かりやすいと思います。Update Animation (アニメーションの更新) というイベントがトリガーされると、Speed がセットされ、Direction (方向) が Calculate (計算) されてから、Direction (方向) がセットされます。
それでは AnimGraph はどのように機能するのでしょうか?EventGraph とはちょっと違います。
上図では、Final Animation Pose (最終アニメーション ポーズ)に至る Walk (歩く) アニメーションが再生されます。評価の順番は、これまで同様左から右ですが、各ノードは、1 回限りの動作というよりもステート (状態) として考えられます。現在のところ、ループするアニメーションは 1 個だけです。それを先に進ませるには、各ノードが一時的なデータを保存しなければなりません。すなわち、ステートです。
範囲が [0, 1] の float 値に基づいて 2 つのアニメーションをブレンドする場合について考えてみます。
アニメーション システムを更新する場合、実行順は次のようになります。
- EventGraph を更新する
- AnimGraph を更新する
- イベントをトリガーする
EventGraph を最初に更新する理由は、すべての更新された変数を取得することができるようになり、それによって AnimGraph がそれらの変数を使ってブレンドできるようになるからです。
これによって、ボーンのトランスフォームに変更が生じることはありません。時間の変化に基づいて事物の「ステート」を更新することしか行われないのです。それでは、いつ、ボーンのトランスフォームを変更して、フレームのための有効なポーズを作り出すのでしょうか?それは、Evaluate で行われます。
AnimGraph では次の 3 つのイベントが発生します。
- Initialize (初期化)
- Update (更新)
- Evaluate (評価)
EventGraph には次の 2 つのイベントしかありません。EventGraph は評価する必要がないからです。
- Initialize (初期化)
- Update (更新)
通常、Initialize (初期化) が発動されるのは一度だけです。ただし、「再初期化が必要な」メッシュを変更した場合は、再度 Initialize を発動することができます。
Update (更新) と Evaluate (評価) は毎ティック発動されます。Evaluate (評価) は有効なポーズの結果を作り出します。これらはなぜ分離されているのでしょうか?ほとんどは最適化のためです。Evaluate (評価) は、トランスフォームについて大量の演算操作を実行するため、アニメーションのプロセスの内で最も高価な部位ですが、ゲームとはインタラクトする必要がないため、簡単に並列処理化することができます。一方、Update (更新) には AnimNotifies などの Trigger Event (トリガー イベント) があるため、しばしば、ブループリントの関数を呼び出すことになります。そのため、ゲームの他の部分とインタラクトする必要が生じ、並列処理化が難しくなるのです。
さて、ボーンのトランスフォームの変更についてですが、どこで実行されるのでしょうか?
たいていの人たちは、ブループリントで処理したいみたいです。確かにブループリントで行う方が気分的には楽でしょうが、適切な場所はアニメーション ブループリントだと私は思います。
これは、アニメーション ブループリントが、すべてのボーンのトランスフォームを計算して最終的な結果を出すものだからです。一箇所で済ますことができればそれに越したことはありません。もしブループリントで行うならば、ティックの順番によっては、ボーンの最新のトランスフォームを取得できない場合も考えられます。次のようなシナリオについて検討してみましょう。
- フレームが開始する。
- ….
- ブループリントがボーンのトランスフォームを更新する。
- アニメーション ブループリントが呼び出される。–すべてのボーンのトランスフォームを更新する。
- ….
- フレームが終了する。
これでは、変更が無効になります。アニメーション ブループリントが、変更の有無を気にしないからです。グラフを実行し、それに従ってトランスフォームを更新するのです。次のように順番を逆にすると、うまく行くでしょう。
- フレームが開始する。
- ….
- アニメーション ブループリントが呼び出される。–すべてのボーンのトランスフォームを更新する。
- ブループリントがボーンのトランスフォームを更新する。
- ….
- フレームが終了する。
しかし、ここでたとえば、変更すべきブループリントが他にもあれば、事態はかなり複雑になるかもしれません。
1 個のインスタンスには 1 個のアニメーション ブループリントが含まれているので、ボーンのトランスフォームに関する操作を集中化させて、アニメーション ブループリントで実行することが最善の方法となります。ボーンのトランスフォームを変更するためには Transform (トランスフォーム) ノードを使用します。
トランスフォームのどのコンポーネントを変更したいのか設定することができます。同様に、どの空間で変更するかも指定できます。
アニメーション ブループリントにはとても強力なツールが備わっています。ノードも多数用意されています。たとえば、layered blending (レイヤーブレンド)、additive animation blending (付加的アニメーション ブレンド)、blend by variables (変数によるブレンド)、state (ステート)、transition (遷移) などがあります。ContentExample プロジェクトには Animation.umap が含まれていますので、是非ご覧になってください。
もっと詳しく知りたい方は次のページをご覧ください。また、感想を残していただけませんか?
https://docs.unrealengine.com/latest/INT/Engine/Animation/AnimBlueprints/index.html