Behavior Tree の概要

Unreal Engine の Behavior Tree の概念と、従来の Behavior Tree との違いについて説明します。

Unreal Engine 5 (Unreal Engine) では、さまざまな方法でキャラクターの AI を作成することができます。Blueprint Visual Scripting を使用すると、キャラクターに対して、アニメーションの再生、特定の位置への移動、何かにヒットしたときの反応などの「アクション」をするように指示することができます。AI キャラクターに独自の思考と意思決定をさせたいときに Behavior Tree が役立ちます。以下に、AI キャラクターがプレーヤーを巡回するか追跡するかを切り替えるビヘイビアツリーの例を示します。

画像をクリックしてフルサイズで表示

Behavior Tree の基本

Behavior Tree は、一部の機能がアタッチされた一連のノードを Behavior Tree グラフに追加および接続することによって、ブループリントと同様の視覚的な方法で作成されます。Behavior Tree がロジックを実行している間、ブラックボード という別のアセットが情報 (ブラックボード キー という) を格納するために使用されます。一般的なワークフローとしては、ブラックボードを作成し、ブラックボード キーをいくつか追加してから、Blackboard アセットを使用する Behavior Tree を作成します (以下の図では、Behavior Tree にブラックボードが割り当てられています)。

A Blackboard is assigned to a Behavior Tree

Unreal Engine の Behavior Tree は、ロジックを左から右、そして上から下に実行します。操作の数値順は、グラフに配置されたノードの右上に表示されます。以下の画像では、Behavior Tree グラフの左端に配置されたブランチのサンプルにいくつかのノードがあり、ブラックボード キーである HasLineOfSight が設定されていれば、プレイヤーを追跡するよう AI に指示しています。

The numerical order of operation can be viewed in the upper-right corner of nodes placed in the graph

上の画像では青いノードが デコレーター (または他の Behavior Tree システムでは「条件式」という) です。これは、 Composite ノードにアタッチされ、ブラックボード キーが true か false かの検証に使用されます。これにより、残りのブランチを実行できるかどうかが決まります。紫色のノードは Task ノードで、AI が実行できるアクションです。

Behavior Tree の作成と編集の詳細については、「Behavior Tree ユーザー ガイド」を参照してください。

Behavior Tree とロジックを作成したら、ゲームプレイ中に Behavior Tree を実行する必要があります。通常は ポーン (すなわち、キャラクターなどのエンティティである AI の「ボディ」) があり、ポーンには関連付けられた AI コントローラー があり、アクション (その 1 つは、Behavior Tree を実行すること) を実行する際にポーンの制御や指示に使用されます。以下では、ポーンにカスタム AI Controller クラスを割り当てます。

Assigned a custom AI Controller class to our Pawn

AI コントローラーは、コントローラーがポーンの「占有」を取得すると、Behavior Tree が実行されます。

In our AI Controller when the Controller takes "possession" of the Pawn we run a Behavior Tree

ポーンで環境内を移動するには、レベルに ナビメッシュ バウンズ ボリューム を追加する必要があります。

Behavior Tree を使用した AI の設定については、「Behavior Tree のクイックスタートガイド」を参照してください。

Unreal Engine の Behavior Tree の違い

このセクションでは、従来の Behavior Tree システムと比較した場合の Unreal Engine には Behavior Tree の違いについて説明します。

Behavior Tree がイベント駆動型である

Unreal Engine には の Behavior Tree が他の Behavior Tree システムと異なる点の 1 つは、Unreal Engine には の Behavior Tree は、フレームごとに不要な作業を行わないようにイベント駆動型であることです。Behavior Tree は、関連付けられた変更が発生したかどうかを常にチェックする代わりに、ツリー内の変更をトリガーするために使用できる「イベント」を受動的にリッスンします。下の画像では、イベントを使用して Blackboard Key の HasLineOfSight? を更新しています。これにより、優先度の高い左端のブランチを実行するために、優先度の低いタスクが中止されます。

画像をクリックしてフルサイズで表示

イベント駆動のアーキテクチャーを持つことで、パフォーマンスとデバッグの両方が改善されます。ただし、これらの改善を最大限に活用するには、Unreal Engine の Behavior Tree とのその他の違いを理解し、Behavior Tree を適切に構成する必要があります。コードはツリー全体を 1 ティックごとに繰り返す必要がないため、パフォーマンスは大幅に向上します。概念上は、常に「もういますか?」と尋ねるのではなく、「もういます!」と言われるまでただ休んでいるようなものです。

動作を視覚的にデバッグするためにビヘイビアツリーの実行履歴を前後に移動する場合は、履歴に関連する変更を表示して無関係な変更は表示しないようにすることをお勧めします。Unreal Engine のイベント駆動の実装では、最初から追加のイテレーションの必要がないため、ツリーに対してイテレーションをして以前と同じ動作を選択した無関係なステップを除外する必要はありません。代わりに、ツリー内の実行位置またはブラックボード値への変更のみが重要であり、表示されるのはそれらの違いです。

条件式がリーフ ノードではない

Behavior Tree の標準モデルでは、条件式は Task リーフ ノードであり、成功または失敗を返す以外の処理は行いません。従来の条件式のタスクは正常に実行できますが、条件式用には デコレーター を使用することを強くお勧めします。

条件式をタスクではなくデコレーターで作成すると、かなり有利な点がいくつかあります。

  1. 条件式をデコレーターにすると、Behavior Tree の UI がより直感的で見やすくなります。

  2. すべてのリーフはアクション タスクであるため、ツリーによって実際のアクションがどのような順序付けられているかを簡単に確認できます。

条件は、制御しているサブツリーのルートにあるため、条件が一致しない場合は、ツリーのどの部分が「遮断されている」のかすぐに確認できます。また、すべてのリーフはアクション タスクであるため、アクションの内容を簡単に確認できます。従来のモデルの場合、条件式がリーフの中にあるので、条件式のリーフとアクションのリーフを見分けるための時間が長くかかってしまいます。

The Decorators Close Enough and Blackboard can prevent the execution of the Sequence node's children

上の Behavior Tree のセクションでは、デコレーターの Close Enoughブラックボード により、Sequence ノードの子ノードの実行を妨げることができます。条件式をデコレーターにするもう 1 つの利点は、これらのデコレーターをツリー内の重要なノードで (イベントを待機する) オブザーバーとして機能させることが簡単な点です。この機能は、ツリーのイベント駆動型の特性を最大限に活用するために重要です。

同時動作

標準的な Behavior Tree は、Parallel Composite ノードを使用して同時にビヘイビアを処理することが多く、Parallel ノードはそのすべての子に対して同時に実行を開始します。これらの子ツリーのいずれかが終了した場合の動作については、特別なルールで定義されています (必要なビヘイビアに応じて)。

Parallel ノードは必ずしもマルチスレッド (タスクの同時実行) である必要はありません。概念的には、これらは複数のタスクを一度に実行するための手段にすぎません。多くの場合、それらは同じスレッド上で実行され、あるシーケンスで開始する場合も多いです。このシーケンスはすべて同じフレーム内で発生するため無関係であるはずですが、重要な場合もあります。

複雑な Parallel ノードの代わりに、Unreal Engine の Behavior Tree では、Simple Parallel ノードと特殊なノード タイプである サービス 、そして デコレーターObserver Aborts プロパティを使用することで、同様の動作を実現しています。

Simple Parallel ノード

Simple Parallel nodes have only two children

Simple Parallel ノードは、2 つの子ノードのみを持つことができます。1 つはシングル Task ノード (オプションのデコレーター) でなければならず、もう 1 つは完全なサブツリーです。Simple Parallel ノードは、「A をしている間に B もするノード」と考えてみてください。例えば、「敵を攻撃しながら、敵に向かって前進する」という状況です。A がプライマリ タスクになり、B は A の完了を待機している間のセカンダリ、あるいはフィラー タスクです。

セカンダリタスク (タスク B) の処理方法についてはいくつかのオプションがありますが、このノードは従来の Parallel ノードに比べて概念的には、比較的単純です。単純ではありますが、Parallel ノードが提供する一般的な使用法のほとんどをサポートしています。Simple Parallel ノードでは、イベント駆動の最適化を簡単に使用できますが、Full Parallel ノードでは、最適化がはるかに複雑になります。

Services

サービス は、任意の Composite ノード (Selector、Sequence、または Simple Parallel) に関連付けられた特別なノードであり、指定した秒数ごとにコールバックを登録し、定期的に発生する必要のあるさまざまな種類の更新を実行することができます。

たとえば、あるサービスを使用すると、Pawn はその Behavior Tree で現在の敵に向かって正常に動作し続けながら、AI Pawn が追跡するのに最適な敵を判断できます。

そのサービスが追加された Composite ノードのサブツリーに実行中のツリーが残っている限り、サービスはアクティブのままです。

Observer Aborts

標準的な Parallel ノードの一般的な使用例の 1 つは、常に条件をチェックし、タスクが必要とする条件が偽になった場合にタスクを中断できるようにすることです。

たとえば、「Hiss」や「Pounce」などのシーケンスを実行する猫がいる場合、マウスが穴の中に逃げ込んだらすぐに諦めるという処理を実行できます。Parallel ノードを使うと、マウスに飛びかかることができるかどうかを子ノードが確認し、別の子ノードがシーケンスを実行します。Unreal Engine の Behavior Tree は、イベント駆動型であるため、条件式デコレーターに値を監視させて、必要に応じて中断します。この例では、シーケンス上に「Observer Aborts」設定が「Self」に設定されている「Mouse Can Be Pounced On?」デコレーターがあるだけです。

同時動作での Unreal Engine のアプローチのメリット

Unreal Engine が同時動作を処理する方法には、主に 次の 3 つのメリットがあります。

  1. 明確さ- サービスと Simple Parallel ノードを使用すると、わかりやすくシンプルなツリーが作成されます。

  2. デバックのしやすさ- グラフが明確になると、デバッグが簡単になります。また、同時実行パスが少ないほど、何が実行されているかがわかりやすくなります。

  3. 最適化のしやすさ - イベント駆動型のグラフは、同時に多数のサブツリーが実行されていなければ、最適化が簡単です。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル