Behavior Tree ノード (基本クラス ) は、タスク、ロジック フロー制御、データ更新を含む、ビヘイビア ツリーの主要な作業を実行します。
Behavior Tree ノードのタイプ
ビヘイビア ツリーの開始点として機能するノードは、Root ノード です。Root ノードはツリー内で一意のノードであり、いくつかの固有のルールがあります。接続は 1 つのみで、Decorator ノード または Service ノード のアタッチはサポートしていません。Root ノード自体にはプロパティはありませんが、選択すると [Details (詳細)] パネルに ビヘイビア ツリー のプロパティが表示され、ビヘイビア ツリーの Blackboard アセット を設定することができます。
Root ノードの他に、次の 4 つのタイプの Behavior Tree ノードがあります。
ノードタイプ | 説明 |
---|---|
Composite Nodes | ブランチのルートを定義し、そのブランチの実行方法の基本的なルールを定義するノードです。 |
Task Nodes | ビヘイビア ツリーのリーフにあたる部分で、これらは実行可能なノードですが出力接続はありません。 |
Decorator Nodes | 条件式とも呼ばれ、他のノードにアタッチされ、ツリーのブランチあるいはノード 1 つでも実行可能かどうかの判断をするノードです。 |
Service Nodes | Composite ノードにアタッチされ、ブランチが実行されている限り、定義された頻度で実行されます。多くの場合、ブラックボードの確認や更新に使用されます。これらは、他のビヘイビア ツリー システムの従来の Parallel ノードに代わるものです。 |
Behavior Tree ノードのインスタンス化ポリシー
Behavior Tree ノード (ここでは「ノード」と呼ぶ) は共有オブジェクトとして存在します。つまり、同じビヘイビア ツリーを使用するすべてのエージェントが、ノード インスタンスの単一セットを共有します。これにより、メモリ使用量を削減しながら CPU パフォーマンスを向上するだけでなく、ノードでエージェント固有のデータが格納されないようにします。ただし、エージェントがノードに関連する情報を格納および更新する必要がある場合のために、UE4 では次の 3 つのソリューションを提供しています。
ノードをインスタンス化する
ノードのbCreateNodeInstance
変数が「true
」に設定されると、ビヘイビア ツリーを使用する各エージェントにノードの一意のインスタンスが付与され、パフォーマンスとメモリ使用量を犠牲にして、エージェント固有のデータを安全に格納します。UBTTask_BlueprintBase
、UBTTask_PlayAnimation
、UBTTask_RunBehaviorDynamic
を含む特定の UE4 のノード クラスが、この機能を使用します。
ブラックボードに格納する
一般的な解決策は、変数をブラックボードに格納することです。このためには、ノードの変数の名前を公開し、ノードの初期化中にその名前を使用してブラックボード キーを取得して格納します。次に、ブラックボード キーを使用して、エージェントのブラックボード インスタンスで変数の値を取得および設定できます。この方法は、bool
、float
、FVector
、int32
、enum
(uint8
として格納) および「UObject*」型の変数をサポートします。
Behavior Tree ノードに格納する
ノードのメモリ内に変数を格納するカスタム構造体またはクラスを作成できます。例えば、UBTTask_MoteTo
クラスは FBTMoveToTaskMemory
を使用します。「BTTask_MoteTo.h」には次のコードが含まれています。
struct FBTMoveToTaskMemory
{
/** Move request ID */
FAIRequestID MoveRequestID;
FDelegateHandle BBObserverDelegateHandle;
FVector PreviousGoalLocation;
TWeakObjectPtr<UAITask_MoveTo> Task;
uint8 bWaitingForPath :1;
uint8 bObserverCanFinishTask :1;
};
UBTNode
の多くの仮想関数は、ノードのメモリに uint8* パラメータを取ります。このパラメータは、エージェントに割り当てられたメモリのブロックを示します。そのサイズは、GetInstanceMemorySize
のオーバーライドされたバージョンによって返されます。ノードはこの量のメモリを各エージェントに割り当て、パフォーマンスを最適化するためにこのメモリを単一の連続するブロックに格納します。ただし、このメモリは UObject エコシステムの一部ではなく、UE4 のリフレクション システムの一部でもないため、ガベージ コレクションで認識されません。このため、UPROPERTY
サポートは利用できません。UObject
ポインタを格納する必要がある場合は、TWeakObjectPtr
をお勧めします。