【Unreal Engine】Behavior Treeで敵AIを実装する:BlackboardとTask/Decoratorの基本

作成: 2025-12-12

敵AIの意思決定を管理するBehavior Treeの基本的な使い方を紹介。Blackboardによるデータ共有、Selector/Sequence/Decorator/Taskノードの役割、索敵・追跡・攻撃といった典型的な行動パターンの実装方法などを整理。

Behavior Treeの概要

Unreal Engineでゲーム開発を進める中で、「敵AIの動きが単調で面白くない」「複雑な状況判断をさせようとするとBlueprintがスパゲッティコードになってしまう」といった課題に直面していませんか?

特に、プレイヤーの発見、追跡、攻撃、そして見失った際の巡回といった、複数の行動を状況に応じて切り替えるAIを実装しようとすると、従来のステートマシン(State Machine)では管理が非常に煩雑になりがちです。

本記事では、このような複雑なAIの意思決定を、視覚的かつ階層的に 設計できるUnreal Engineの強力なAIツール、Behavior Tree(ビヘイビアツリー) について、その基本概念から、初心者でもすぐに実践できる具体的な実装手順までを、豊富なBlueprint例とともに徹底的に解説します。

Behavior Treeとは

Behavior Treeは、AIが「次に何をすべきか」を決定するための階層的な意思決定構造です。ツリーのルートから始まり、ノードを辿りながら、AIの行動を上から順に、あるいは条件に応じて実行していきます。

主要な構成要素

Behavior Treeを理解する上で、以下の3つの主要な要素は欠かせません。

要素名役割詳細
Behavior Tree (BT)意思決定の構造AIの行動ロジック全体を定義するツリー構造。
Blackboard (BB)AIのメモリ/データAIが共有するデータ(ターゲットの位置、HP、現在の状態など)を格納する場所。BTのノードはBBの情報を参照・更新して動作を決定します。
AI ControllerAIの制御役BTとBBを所有し、Pawn(キャラクター)を操作するコントローラー。

ノードの種類

Behavior Treeは、主に以下の4種類のノードで構成されます。

  1. コンポジットノード (Composite Nodes): 子ノードの実行順序を制御します。
    • Sequence (シーケンス): 子ノードを左から順に実行し、すべて成功した場合に成功を返します。途中で失敗した場合は、その時点で失敗を返します。
    • Selector (セレクター): 子ノードを左から順に実行し、いずれか一つが成功した場合に成功を返します。すべて失敗した場合に失敗を返します。
  2. タスクノード (Task Nodes): AIに具体的な行動(移動、攻撃、待機など)を実行させるノードです。通常、カスタムのBlueprintまたはC++で作成します。
  3. デコレーターノード (Decorator Nodes): 子ノードの実行可否を判断する条件ノードです。Blackboardの値やAIの状態をチェックします。
  4. サービスノード (Service Nodes): 一定間隔で実行され、Blackboardの値を更新したり、周囲の状況を監視したりするノードです。

敵AIの実装例

ここでは、最も一般的な敵AIの動作である「プレイヤーの索敵(パトロール)」「発見後の追跡」「一定距離での攻撃」をBehavior Treeで実装する手順を解説します。

AI ControllerとBlackboardの設定

まず、AIを制御するための基本設定を行います。

  1. AI Controllerの作成: AIControllerクラスを継承したBlueprintを作成し、敵PawnのデフォルトAIコントローラーに設定します。
  2. Blackboardの作成: コンテンツブラウザで右クリックし、Artificial Intelligence -> Blackboardを選択してBlackboardアセットを作成します。
  3. Blackboard Keyの追加: 作成したBlackboardを開き、以下のKeyを追加します。
    • TargetActor (Object型): プレイヤーなど、AIが追跡・攻撃するターゲット。
    • IsTargetDetected (Boolean型): ターゲットを発見したかどうか。
    • PatrolLocation (Vector型): 巡回目標地点。
  4. Behavior Treeの作成: Artificial Intelligence -> Behavior Treeを選択してBTアセットを作成します。BTアセットを開き、詳細パネルのBlackboard Asset にBlackboardアセットを設定します。AI ControllerではRun Behavior TreeノードでこのBTアセットを指定するだけで、Blackboardは自動的に関連付けられます。

💡 Blackboardの設定場所

BlackboardはBTアセット側で設定するのが一般的です。AI Controller側ではBTアセットのみを指定し、Blackboardを別途指定する必要はありません。

Behavior Treeの設計

AIの意思決定は、以下のロジックで構成します。

AIのロジック:

  1. Selector: ターゲットを発見しているか?
  2. YESの場合 (Sequence): ターゲットを追跡し、攻撃する。
  3. NOの場合 (Sequence): 巡回(パトロール)する。

索敵(Serviceノード)の実装

AIがプレイヤーを発見したかどうかを定期的にチェックするロジックをServiceノードで実装します。

  1. Serviceノードの作成: BTService_BlueprintBaseを継承したBlueprint(例: BTS_CheckForTarget)を作成します。
  2. ロジックの実装: Receive Tick AIイベントで、Sphere TraceGet Actors in Rangeなどを使用してプレイヤーを索敵します。
  3. Blackboardの更新: プレイヤーを発見した場合、BlackboardのTargetActorにプレイヤーを設定し、IsTargetDetectedTrueに設定します。見失った場合はFalseに戻します。
  4. BTへの配置: Behavior Treeのルート直下のSelectorノードに、このServiceノードをアタッチします。

💡 より効率的な索敵:AIPerceptionコンポーネント

Serviceノードでの定期的な索敵(Tickベース)は簡単ですが、パフォーマンスの観点からはAIPerceptionComponent の使用が推奨されます。AIPerceptionは** イベント駆動型** であり、OnTargetPerceptionUpdatedイベントを使ってターゲットを検知したときだけBlackboardを更新できます。多数のAIが存在する大規模なゲームでは、この方法の方が効率的です。

追跡と攻撃(Taskノード)の実装

  1. 追跡Task: 標準のMove Toタスクノードを使用します。このノードのBlackboard Keyに、Blackboardで作成したTargetActorを指定します。
  2. 攻撃Task: BTTask_BlueprintBaseを継承したBlueprint(例: BTT_AttackTarget)を作成します。
    • Receive Execute AIイベントで、攻撃アニメーションの再生やダメージ処理を行い、Finish ExecuteノードでSuccessを返します。

💡 ベストプラクティス:条件判断はDecoratorで分離

上記の攻撃Taskでは「攻撃可能距離内かどうか」をTask内でチェックすることも可能ですが、Decoratorノード で距離チェックを分離する方が推奨されます。例えばBTDecorator_IsAtLocationやカスタムDecoratorを使い、攻撃可能距離内のときだけ攻撃Taskが実行されるようにします。これにより、Taskは純粋に「攻撃する」という行動のみに専念でき、条件と行動が明確に分離されます。

巡回(Taskノード)の実装

  1. 巡回地点設定Task: カスタムTask(例: BTT_FindPatrolLocation)を作成し、ランダムな巡回地点を計算してBlackboardのPatrolLocation Keyに設定します。
  2. 巡回移動Task: 標準のMove Toタスクノードを使用し、Blackboard KeyPatrolLocationを指定します。

ベストプラクティス

Behavior Treeは強力ですが、設計を誤るとすぐに複雑化します。以下のベストプラクティスを意識して設計しましょう。

BlackBoardの設計を最優先する

Behavior Treeの真の力は、Blackboardによるデータ駆動型の意思決定にあります。

  • データの一元管理: AIの状態(攻撃中、巡回中など)や重要な情報(ターゲット、HP、弾薬数)はすべてBlackboardに格納し、ノード間で直接データをやり取りしないようにします。
  • Keyの命名規則: Keyには明確な命名規則(例: Target_Player, State_Patrolling)を設け、どのノードがどのKeyを参照・更新しているかを分かりやすくします。

ノードの役割を明確にする

  • Taskノードは「行動」のみ: Taskノード内では、移動や攻撃といった具体的な行動 のみを実行し、条件判断 はDecoratorに任せます。
  • Decoratorノードは「条件」のみ: DecoratorはBlackboardの値をチェックする純粋な条件判断 に徹し、Blackboardの値を変更するなどの副作用を持たせないようにします。

よくある間違い

よくある間違い解決策(ベストプラクティス)
無限ループ: TaskノードがFailureを返し続け、Selectorノードがすぐに次の子ノードに移ってしまう。Taskノード内でWaitDelayを適切に使用し、実行頻度を調整する。または、Finish ExecuteSuccessを返す条件を明確にする。
頻繁すぎるService: Serviceノードの実行間隔(Interval)が短すぎるため、パフォーマンスが低下する。索敵など、頻繁なチェックが必要な処理でも、最低0.2秒~0.5秒程度のIntervalを設定する。また、必要な時だけServiceを実行するようDecoratorで制御する。
Blackboard Keyの誤用: 異なる意味を持つデータに同じKeyを使い回してしまう。Keyは用途ごとに明確に分け、特にVectorObject型は、TargetLocationPatrolLocationのように区別して使用する。

Behavior Tree活用のポイント

Behavior Treeは、Unreal Engineで複雑な敵AIを実装するための最も強力で推奨される手法です。

  • 階層的な設計: 複雑な意思決定をSequenceやSelectorで階層的に整理できます。
  • データ駆動: Blackboardを中心にデータを管理することで、ノード間の依存関係を減らし、再利用性を高めます。
  • 視覚的なデバッグ: エディタ上でAIの実行パスをリアルタイムで確認できるため、デバッグが容易です。

本記事で紹介した基本概念と実装手順を参考に、あなたのゲームに深みを与える、賢く、そして手強い敵AIを設計してみてください。

💡 より高度なAIへ:EQS(Environment Query System)

Behavior Treeは意思決定の構造を提供しますが、「どこに移動するか」「どのターゲットを選ぶか」といった環境に基づいた選択 にはEQS(Environment Query System) が効果的です。EQSは、周囲の環境をスキャンし、最適な位置やターゲットをスコアリングして選択できます。BTとEQSを組み合わせることで、より賢く状況適応的なAIを実現できます。