アニメーションツリー¶
はじめに¶
AnimationPlayerと合わせて、Godotはあらゆるゲームエンジンの中でもトップクラスの柔軟性をもつアニメーション・システムをもっています。トランスフォーム、ベジェ曲線、関数呼び出し、オーディオや副アニメーションのトラックが用意されているのみならず、あらゆるノードやリソースのどんなプロパティでもアニメーションできることは、非常に独特です。
ただし、それらのアニメーションをブレンドするには、AnimationPlayer
では固定のクロスフェード遷移のみなので、比較的制限されています。
AnimationTreeは、高度な遷移をするためにGodot 3.1で導入されたノードです。これは古いAnimationTreePlayer
を置き換えるもので、膨大な量の機能と柔軟性を加えています。
AnimationTreeの作成¶
始める前にまず明らかにすべきは、AnimationTree
ノードは自身のアニメーションは含みません。代わりにそれは、別にあるAnimationPlayer
ノードが持つアニメーションを利用します。これにより、従来通りアニメーションを編集(あるいは他の3Dシーンからインポート)でき、さらに再生をコントロールしたいときにこのノードを追加するのです。
AnimationTree
の最も一般的な使い道は3Dシーンです。シーンを3D交換フォーマットからインポートすると、通常はアニメーションはそのまま同梱されています(複数のものや、大きなものがインポートの際に分割されていても)。インポートされたGodotシーンでは最終的に、アニメーションはすべて一つのAnimationPlayer
ノードに格納されます。
Godotでは、インポートされたシーンを (インスタンス化あるいは継承せずに) 直接使うことは珍しいので、インポートされたシーンのための新しいシーンにAnimationTree
を追加することにします。そのあとAnimationTree
ノードにて、インポートされたシーンの中に作られたAnimationPlayer
を割り当ててください。
参考例として、三人称視点シューターデモ(英語) もそうなっています。

プレイヤー用の新しいシーンはKinematicBody
をルートにして作られています。このシーンの中には、元の.dae
(Collada)ファイルがインスタンス化され、AnimationTree
ノードが作成されてあります。
ツリーの作成¶
AnimationTree
では主に3種類のノードが使えます:
- アニメーション・ノード。リンクされた
AnimationTree
のアニメーションを参照します。 - アニメーションルート・ノード。副ノードとのブレンドに使われます。
- アニメーションブレンド・ノード。
AnimationNodeBlendTree
の中で使用され、複数のインプットポートを持ち、一つのグラフでブレンドします。
AnimationTree
のルートノードを設定するには、いくつかの型が用意されています:

AnimationNodeAnimation
: リストから選択したアニメーションを再生します。これは一番シンプルなルートノードで、通常は直接のルートとしては使用されません。AnimationNodeBlendTree
: mix、blend2、blend3、one shotなどのような、多くのブレンド型のノードを含んでいます。これはルートとしてよく使われるものの一つです。AnimationNodeStateMachine
: 一つのグラフに、複数のルートノードを子に持ちます。それぞれのノードはステートとして扱われ、ステートを切り替えるための機能をいくつも備えています。AnimationNodeBlendSpace2D
: ルートノードを2Dブレンドスペースに置けるようになります。二次元空間でブレンド位置をコントロールし、複数のアニメーションのミックスします。AnimationNodeBlendSpace1D
: 上記の簡略版です (一次元)。
ブレンド・ツリー¶
AnimationNodeBlendTree
はブレンド用で、ルートまたは通常のノードを含むことができます。ノードはメニューからグラフに追加します。

すべてのブレンドツリーには、標準でOutput
ノードが入っていて、アニメーションを再生するにはそこに何かをつなげる必要があります。
この機能を確認する一番簡単な方法は、Animation
ノードを直接つなげることです:

これは単純にアニメーションを再生します。実行する前にまずAnimationTree
がアクティブであることを確認してください。
下記は利用可能なノードの短い説明です:
Blend2 / Blend3¶
これらのノードは、2つあるいは3つのインプットをユーザー指定の値でブレンドします:

より複雑なブレンドには、代わりにブレンドスペースを使うことをおすすめします。
ブレンドにはフィルターを使うこともでき、どのトラックをブレンド関数に渡すかどうかをコントロールできます。これはアニメーションをレイヤーに分けて重ね合わせるのに有用です。

Seek¶
このノードは、グラフのどんな副子ノードに対してもシーク命令を送ります。時間をセットした後は、値は -1 に戻ります。
TimeScale¶
アニメーションの再生速度の変更 (あるいは逆再生) を可能にします。0 にセットするとアニメーションを一時停止します。
トランジション¶
とても単純なステートマシンです (StateMachine
ノードを扱いたくない時に)。複数のアニメーションを接続でき、トランジションの時間を指定できます。
BlendSpace2D¶
BlendSpace2D
is a node to do advanced blending in two dimensions. Points are added to a two-dimensional space and then a position
can be controlled to determine blending:

X および Y の範囲でコントロールできます (それぞれ別の名称に変更可)。デフォルトでは、点はどこにでも置けます(座標系の上で右クリックするか、点を作成ボタンを使う)。三角形はドロネー分割で自動生成されます。

三角形の自動作成をオフにすれば、三角形を手動で作成することもできますが、必要になることはあまり無いでしょう:

最後に、ブレンドモードは変更することができます。標準状態では、一番近い三角形の中で補完された点によってブレンドされますが、もし対象が(フレームごとに動かす)2Dアニメーションなら、離散モードに切り替えてもよいでしょう。あるいは、離散アニメーション間においても現在の再生位置を維持したい場合のために、キャリーモードもあります。モードはブレンドメニューから変更できます。

BlendSpace1D¶
これは2Dブレンドスペースと同様ですが、一次元のみです (そのため三角形は不要)。
StateMachine¶
このノードは比較的シンプルなステートマシンです。ルートノードを作り、線をつないで接続します。ステートは、独自のプロパティを持つトランジションを用いて接続します。トランジションは一方通行ですが、ふたつを互いに接続させあうことができます。

トランジションにはいくつもの種類があります:

- 即座 (Immediate): 次のステートへと即座に切り替わります。現在のステートが終わると、新しいほうの先頭から始まります。
- 同期 (Sync): 次のステートへと即座に切り替わりますが、新しいステートでも古いステートと同じ再生位置になります。
- 終わりに (At End): 現在のステートの再生位置が最後になるまで待ち、それから次のステートの先頭に切り替わります。
トランジションはまた、いくつかのプロパティを持ちます。トランジションをクリックすると、インスペクタ ドックに表示されます:

- Switch Mode はトランジションの種類です (上記参照)。作成した後でもここで変更できます。
- Auto Advance (自動移行)は、このステートに到達したらすぐにトランジションがオンになります。これは At End スイッチモードと合わせるのが最適です。
- Advance Condition (移行条件) は、この条件が満たされた場合に自動移行させます。テキストフィールドには変数名を入れます。この変数はコードから変更することができます (詳しくは後述)。
- Xfade Time は、このステートと次との間でのクロスフェードにかかる時間です。
- Priority (優先度) は、コード内での
travel()
関数と共に使用します (詳しくは後述)。ひとつのステートから別へと移動するときの、このノードの優先度を設定します。 - Disabled (無効) は、このトランジションを無効にします (ただし travel や自動移行では無視されます)。
ルート モーション¶
3Dアニメーションの作業では、スケルトンを動かすためにルート・スケルトン ボーンを用意するのが一般的なテクニックです。これにより、キャラクターを床に合わせて歩かせることが可能になります。また、ムービー場面においても、正確に物体に触れさせられるようになります。
Godot内でアニメーションを再生するときは、このボーンを ルート・モーション トラック に指定することができます。そうすると、そのボーンの見た目の変化は打ち消されます (アニメーションはそのまま)。

そのあと、実際のモーションはAnimationTree APIからトランスフォームとして取得します:
anim_tree.get_root_motion_transform()
animTree.GetRootMotionTransform();
これをKinematicBody.move_and_slideなどの関数に渡すことで、キャラクターの動きをコントロールできます。
また、ツールノードとしてRootMotionView
があり、シーン中に置くことでキャラクターとアニメーション用のフロアが表示されます (通常このノードはゲーム中は無効にされます)。

コードからコントロールする¶
ツリーを作成してプレビューしたら、最後に残る質問は「これを全部コードからコントロールする方法は?」です。
注意していただきたいのは、アニメーション ノードはリソースであり、したがって、すべてのインスタンス間で共有されます。ノードの値を直接変更すると、このAnimationTree
を使用するシーンにある、すべてのインスタンスも影響を受けます。しかし、これにはクールな応用方法もあります。例えば、アニメーションツリーの一部をコピー&ペーストできますし、(ステートマシンやブレンドスペースのような)複雑なレイアウトのノードを、異なるアニメーションツリー間で再利用できます。
実際のアニメーション データはAnimationTree
ノードに格納されており、プロパティを通じてアクセスします。AnimationTree
の Parameters セクションに、リアルタイムで変更できるパラメーターが全てあるので確認してみてください:

This is handy because it makes it possible to animate them from an AnimationPlayer
, or even the AnimationTree
itself,
allowing the realization of very complex animation logic.
これらの値をコードから変更する場合は、プロパティ パスを知る必要があります。それには、パラメーターの上にマウスをホバーするだけです。

そうすれば、それらを設定したり読み込めます:
anim_tree.set("parameters/eye_blend/blend_amount", 1.0)
# Simpler alternative form:
anim_tree["parameters/eye_blend/blend_amount"] = 1.0
animTree.Set("parameters/eye_blend/blend_amount", 1.0);
ステートマシン travel¶
GodotのStateMachine
実装にあるナイスな機能のひとつは、travel (移動)です。現在のステートからの移動を指示すると、グラフは中間のものを全て通ってから、別のステートへと移ります。これはA* アルゴリズムにて行われます。
travel機能を使うには、まずAnimationTree
ノードからAnimationNodeStateMachinePlayback オブジェクトを取得します (プロパティのひとつ)。
var state_machine = anim_tree["parameters/playback"]
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/playback");
取得したら、その多くの関数の中からひとつ呼び出せば使えます:
state_machine.travel("SomeState")
stateMachine.Travel("SomeState")