執筆バージョン: Unreal Engine 5.0 |
今回は、UE5に実装されているビヘイビアツリー(Behavior Tree)について説明していきたいと思います。
ビヘイビアツリーとは、敵やNPCなどのAIを作る上で有効な手段の一つで、キャラクターの思考・行動をツリー構造上に配置し、行動に至るまでの思考の流れを視覚的にわかりやすくしたものです。各状況に応じた判断でノードを分岐させ、到達した末端のノードでそこに書かれている行動を行う、というように考えるとわかりやすいと思います。
UE5では、AIに関して実装を行う場合、AIControllerを基底としたクラスブループリントを用いてそこで全てを完結させる事も当然可能ですが、ビヘイビアツリーを用いる事で、視覚的にわかりやすく、より簡潔に、かつ独立的に実装できるため、キャラクターに依存しない保守管理を行うことが出来ます。
構成

UE5のビヘイビアツリーは以下の要素で構成されています。
- ブラックボード
- ルートノード
- コンポジット
- サービス
- デコレーター
- タスク
1つずつ解説していきたいと思います。
ブラックボード
各ノード間で受け渡しが可能な変数を保持するためのデータアセットです。キャラクターのターゲットとなるアクターや座標などを保持することができ、後述するタスクなどの各ノードに受け渡すことができます。

ルートノード
ビヘイビアツリーの実行開始ノードです。各ビヘイビアツリーに必ず一つのみ存在し、ツリー構造での根ノードに当たります。親ノードを持ちません。

コンポジット
SelectorノードやSequenceノードなど、ツリー構造でのブランチの実行ルートを制御するノードです。通常のビヘイビアツリーではParallelノードもこれに当たりますが、UE5ではParallelノードは実装されていません。

タスク
MoveToノードなど、実際にキャラクターに対して処理を行うノードです。このノードによってキャラクターを指定の場所へ動かしたり、止めたりできます。ツリー構造での葉ノードに当たり、子ノードを持つことができません。

サービス
コンポジットノード、タスクノードに追加するような形でアタッチするノードです。ブランチの実行中に指定した頻度(秒数指定)で実行を行います。例えばブラックボードを更新する際などに使用します。中身はサービスクラスを基底としたクラスブループリントです。

デコレーター
コンポジットノード、タスクノードに追加するような形でアタッチするノードです。条件式として使用します。内部に記述されているデコレータークラスのクラスブループリントの判定によって、そのノードやブランチを実行可能かどうかを判断します。また、サービスとデコレーターはコンポジットに複数個アタッチすることが可能なため、複数の処理や条件を同じノード内で判定する事が可能です。

解説
ビヘイビアツリーの実行するノードの流れを制御するコンポジットですが、これの動きを把握する事はとても重要です。SequenceとSelector、Simple Parallelのそれぞれについて詳しく説明したいと思います。
Sequenceノード
左の子ノードから順番にノードを実行していきます。子ノードが成功判定を返したら次の子ノード(兄弟ノード)へと処理を移しますが、もし失敗判定が返ってきてしまった場合は、次の子ノード(兄弟ノード)があってもそれを処理せず、ノードの実行を終了します。子ノードが失敗を返さない限り、隣の子ノード(兄弟ノード)へと処理は移行します。


Selectorノード
左の子ノードから順番にノードを実行していきます。子ノードが成功判定を返した場合、次の子ノード(兄弟ノード)があってもそれを処理せず、ノードの実行を終了します。もし失敗判定が返ってきた場合は、次の子ノード(兄弟ノード)へと処理を移行します。

Simple Parallelノード
複数のタスクを同時並行で実行していきます。メインタスクとセカンダリツリーに分かれています。メインタスクが終了すると、「Finish Mode」の設定によってセカンダリツリーの処理が変わります。「Immediate」の場合は、ノードがすぐに終了してセカンダリツリーを中止します。「Delayed」の場合は、セカンダリツリーの終了を遅らせることができます。たとえば「目的地に移動している間に近くに敵がいればその敵を撃つ」といったことが考えられます。

特にSequence、Selectorの動きはとても重要なものなので、ビヘイビアツリーを使用するにあたってよく理解しておく必要があります。
関連リンク
ビヘイビアツリーの公式ドキュメントには、クイックスタートガイドが存在するので、こちらを見ながら一度作ってみるとより理解が深くなると思います。
クイックスタートガイド:https://docs.unrealengine.com/latest/ja/behavior-tree-in-unreal-engine—quick-start-guide/
ユーザーガイド:https://docs.unrealengine.com/latest/ja/behavior-tree-in-unreal-engine—user-guide/
ノードリファレンス:https://docs.unrealengine.com/latest/ja/behavior-tree-node-reference-in-unreal-engine/