UE5初心者が「ビヘイビアツリー(Behavior Tree)」という敵AI(エネミー)の作戦や行動を決定するシステムについて調べてみた!
- ◆参考動画(必見)
- ◆「プレイヤーを追跡する」敵AIの作り方
- ①ビヘイビアツリーとブラックボードを作成
- ②敵のビヘイビアツリー「BT_AI」を編集
- ※ビヘイビアツリーの各ノードについて
- ③敵の散策タスク「BTTask_RoamAround」を作成
- ④タスクの紐づけ後、敵BP「BP_AI」を作成
- ⑤敵の脳になる「AI_Controller」を作成
- ⑥敵の行動範囲「NavMeshBoundsVolume」を作成
- ⑦敵のブレンドスペース「AIBlendSpace1D」を作成
- ⑧敵のアニメーションBP「ABP_AI」を作成
- ⑨敵がプレイヤーを追跡するタスク「BTTask_ChasePlayer」の作成
- ⑩デコレーター(分岐条件)の挿入
- ⑪敵の目(PawnSensing)を「BP_AI」内に追加
- ◆ビヘイビアツリーの最終的な全体図
- ◆後でやりたい応用編
▼本文は「続きを読む」からどうぞ~!
◆参考動画(必見)
▲世界で1番分かりやすい解説動画(Gorkaさん)。
- 今回は、この動画で解説されている「待機時はウロウロ歩き回っているが、プレイヤー発見後に追尾して来る敵AI」を作る方法についてまとめていくぜ!
◆「プレイヤーを追跡する」敵AIの作り方
①ビヘイビアツリーとブラックボードを作成
- コンテンツブラウザーに新規フォルダー「AI」を作る。
- コンテンツブラウザー右クリ>[Artificial Intelligence]>[Behavior Tree]>「BT_AI」と命名。
- コンテンツブラウザー右クリ>[Artificial Intelligence]>[Blackboard]>「BBD_AI」と命名。
※ビヘイビアツリーとブラックボード(≒情報保管用のメモ帳)は1セットで作成。
②敵のビヘイビアツリー「BT_AI」を編集
[BT_AI]をダブルクリックで開き、右側[Details]欄からブラックボード[BBD_AI]が関連付けられているか確認しておく。
- [Root]から下に線を引き、[Selector]を作成。
※ビヘイビアツリーの実行順は、上から下>左から右! - [Selector]から左下に線を引き、[▼Composites]>[Sequence]を作成。
[Details]欄>[Node Name]から「Look Around」と命名。 - [Selector]から右下へ線を引き、[Sequence]作成>「Chase Player」と命名。
上部ツールバー(左上)から[New Task]を選び、右クリ>[New folder]>新規フォルダー「Tasks」作成。
そのまま「Tasks」フォルダー内に、カスタムタスク「BTTask_RoamAround」を作成して[Save]。
※ビヘイビアツリーの各ノードについて
▲オススメの参考記事(必見)。
【>アンリアルエンジン公式ガイド】でも詳しく解説されている。
- 「Root」=処理の出発地点(灰色)
- 「Composite」=ツリー分岐用ノード(灰色)
①[Sequence]…挫折を許さない完璧主義の厳しい親
子ノードのいずれかが失敗すると子ノード実行停止>失敗判定。
子ノードが全部成功>成功判定。
(途中で失敗しない時に、左端から右端まで処理が続く)
②[Selector]…成功するまで試し続ける甘い親
子ノードのいずれかが成功すると子ノード実行停止>成功判定。
子ノードが全部失敗>失敗判定。
(途中で成功しない時に、左端から右端まで処理が続く)
③[Simple Parallel]…器用で臨機応変な親
メインタスク(A)+セカンダリツリー(B)の構成。Aの間にBもする。
A終了後の[Finish Mode]設定に応じ、Bの処理が変わる。
※Aの[Finish Mode]=[Immediate]なら、A終了後にそのまま中断。
※Aの[Finish Mode]=[Delayed]なら、B終了までに遅延を挟める。
【>コンポジットノードの種類まとめ(公式ガイド)】 - 「Decorater」=分岐の条件(青色)
【>デコレーターノードの種類まとめ(公式ガイド)】 - 「Task」=実行内容のノード(紫色)
ツリーの末端になる実行タスク。子ノードを持てない。
【>BT用タスクノードの種類まとめ(公式ガイド)】 - 「service」=分岐先を実行中、指定した間隔で定期的にループするノード(緑色)
ブラックボードの確認や更新に使う。ループ間隔の指定は秒数単位。
【>サービスノードの種類まとめ(公式ガイド)】
③敵の散策タスク「BTTask_RoamAround」を作成
▼[BTTask_RoamAround]のイベントグラフを以下のように編集する。
- 左側[FUNCTIONS]にカーソルオン>[▼Override]から[Recive Excute AI]を追加。
※[Recive Excute AI]は、[Event BeginPlay]と似ているノード。 - [Finish Excute]を追加し、[Success]欄もONにしておく。
※[Recive Excute AI]ノードは、タスクのゴール地点を指定する[Finish Excute]ノードとセットで使う。
(終点設定を忘れると、終了するタイミングが分からずスタックするから要注意!) - [AI MoveTo]を追加。
- [GetRandomReachablePointInRadius]を追加。
④タスクの紐づけ後、敵BP「BP_AI」を作成
ビヘイビアツリーの全体図[BT_AI]に戻る。
- [Look Around]の下に線を引き、③で作った[BTTask_RoamAround]を挿入する。
- その次に[Wait]を挿入し、[Wait Time(≒ディレイ秒数)]を[2]へ変更。
最低限のビヘイビアツリーができたので、敵BPの作成に移ろう。
- コンテンツブラウザーの[AI]フォルダ内で右クリ>[Blueprint Class]>[Character]からキャラクター型のブループリントを作成し、「BP_AI」と命名。
- ビューポートから[Skeletal Mesh Asset]欄に[SKM_Manny_Simple]を指定し、[Location]と[Rotation]のZ値をどちらも[-90]に設定。
- ※アニメーション設定は後の⑦⑧項で行う。
⑤敵の脳になる「AI_Controller」を作成
まず、新規AIコントローラーを作る。
- [AI]フォルダ内で右クリ>[Blueprint Class]>下側の[▼ALL CLASSES]>[AI Controller]を作り、「AI_Controller」と命名。
「AI_Controller」をダブルクリックし、イベントグラフに移る。
▼以下のようにノードを編集する。
- [Event BeginPlay]の後ろに[Run Behavior Tree]ノードを追加。
- [BTAsset]ピンに、[BT_AI]を指定。
- コンパイル&保存。
[BP_AI]のビュポート欄を開き、上部にある[Class Defaults]をクリックして有効化。
右側[Details]欄から[AI Controller Class]項を[AI_Controller]へ変更。
同じく[Auto Possess AI]項を[Placed in World or Spawned]へ変更。
全部終わったら、[BP_AI]をレベル上の好きな位置にドラッグ&ドロップで配置する。
⑥敵の行動範囲「NavMeshBoundsVolume」を作成
- メイン画面左上にある[+]ボタン>[Volumes]>[NavMeshBoundsVolume]を追加。
- [Details]欄>[Scale]の鍵アイコンをロック後、[X50,Y50,Z50]に一括設定。
(ナビメッシュを大きくすると、敵AIの行動可能エリアがレベル全体まで広がる。
敵AIの行動可能エリアは、[P]キーを押すと緑色に染まるぞ!)
ここまでの①項~⑥項を終わらせたら、一旦テストプレイしてみよう。
[BP_AI]が2秒ごとにランダム移動する(=タスク[BTTask_RoamAround]を2秒ごとに繰り返す)ようになっているはずだ。
⑦敵のブレンドスペース「AIBlendSpace1D」を作成
[AI]フォルダ内に、新規フォルダ[Animations]を作成。
- [Animations]フォルダ内を右クリ>[Animation]>[Legacy]>[Blend Space 1D]>[SK_Manequin]選択>「AIBlendSpace1D」と命名(作成)。
[AIBlendSpace1D]をダブルクリックで開く。
- 左側[AssetDetails]>[▼HorizontalAxis]>[Name]は[Speed]、[Maximum Axis Value(≒ピーク値)]は[600]、[Snap to Grid]をONに設定。
- 右下[AssetBrowser]欄>[MM_Idle]をドラッグし、中央下のタイムライン(左端)へ移動。
- 右下[AssetBrowser]欄>[MM_Run_Fwd]をドラッグし、中央下のタイムライン(右端)へ移動。
▲左端に静止モーション&右端に走行モーションを指定したため、その中間の歩行モーション(中央部分)は静止&走行モーションをブレンドしたモーションになる。
- タイムライン左端が「動作開始時」のモーション。
タイムライン右端が「動作ピーク時」のモーション。 - タイムライン上で開始時モーション(左端)とピーク時モーション(右端)だけ決めれば、中間モーション(真ん中付近)はシステム側が勝手に補完する。
- 緑色のバツ印=再生プレビュー地点は、タイムライン上で[Ctrl]を押しながらカーソルを動かすと動く(バツ印がある地点の補完モーションを再生できる)。
▲「ブレンドスペース(モーションA⇔B間を自動で滑らかに繋げる機能)」の解説記事。
⑧敵のアニメーションBP「ABP_AI」を作成
[Animations]フォルダ内を右クリ>[Animation]>[Animation Blueprint]>[SK_Mannequin]>[Create]>「ABP_AI」と命名(作成)し、ダブルクリックから編集。
▼まず[ABP_AI]のアニメグラフ(Anim Graph)タブを以下の通りに編集する。
- [ABP_AI]の右下[Asset Browser]欄より⑦で作った[AIBlendSpace1D]を[AnimGraph]画面へ追加。
- [AIBlendSpace1D]の人型ピンから[Slot'Defaultslot']を追加。
- [AIBlendSpace1D]の[Speed]ピンを右クリ>[Promote to Variables]で変数へ昇格。
▼次に、[ABP_AI]のイベントグラフ(Event Graph)タブを以下のように編集する。
- 編集後、[BP_AI]のビューポートを開き、右側[Anim Class]に[ABP_AI]を指定。
- [▼Pawn]>[Use Controller Rotation Yaw]を無効化。
- [Use Controller Desired Rotation]を有効化。
※動画内だとこれで走行モーションが反映されているけど、5.3ではなぜか走行モーションだけ反映されずアイドル(待機)状態でホバー移動してしまった。
- 【5.3でブレンドスペースが反映されない問題(?)の解決方法】
- ①[ABP_AI]内の[AnimGraph]で、[AIBlendSpca1D]ノードをダブルクリック。
- ②編集用タイムラインが出てきたら、右下[Asset Browser]欄から[MM_Run_Fwd]をドラッグして、タイムライン右端へ配置後に「MM_Run_Fwd」と命名。
- これで動画のように静止⇔走行のブレンドスペースが反映された。
(⑦でちゃんと走行モーションを設定して保存したはずだけどミスってたかも?)
⑨敵がプレイヤーを追跡するタスク「BTTask_ChasePlayer」の作成
ビヘイビアツリーの全体図[BT_AI]に戻る。
左上[New Task]>[BTTask_RoamAround]>[Tasks]フォルダ内に、カスタムタスク[BTTask_ChasePlayer]を作成。
▼[BTTask_ChasePlayer]のイベントグラフを以下のように編集する。
- 左側[FUNCTIONS]カーソルオン>[▼Override]から[Recive Excute AI]を追加。
- [Finish Excute]を追加し、[Success]欄もONにしておく。
- [AI MoveTo]を追加。
- [Get Player Character]を追加。
ビヘイビアツリーの全体図[BT_AI]へ戻り、[Chace Player]の下に[BTTask_ChasePlayer]を挿入。
⑩デコレーター(分岐条件)の挿入
▼[Look Around]部分にデコレーターを追加していく。
- [Look Around]右クリ>[Add Decorator]>[Brackboard]を追加。
- 右側[Details]欄>[Observer aborts]>[Self]に設定。
- 右上[Brackboard]タブ>左上[New Key]>Bool型で[hasSeenPlayer?]作成。
- 右上[Behavior Tree]タブへ戻る。
- [Look Around]の[Blackboard Based Condition]クリック>[Details]欄で[Key Query]を[Is Not Set]、[Brackboard Key]を[hasSeenPlayer?]に変更。
▼[Chase Player]部分にデコレーターを追加していく。
- [Chase Player]右クリ>[Add Decorator]>[Brackboard]を追加。
- 右側[Details]欄>[Observer aborts]>[Self]に設定。
- [Chase Player]の[Blackboard Based Condition]クリック>[Details]欄で[Key Query]を[Is Set]、[Brackboard Key]を[hasSeenPlayer?]に変更。
▲デコレーターの各項目について(公式ガイド)。
[Key Query]とは?>条件式を指定する項目。
[Is Set]=セットされている=値を持っている。ブーリアンなら真(True)。
[Is Not Set]=セットされていない=値が無い。ブーリアンなら偽(False)。
[Observer aborts]とは?>中断条件を指定する項目。
[Self]=オブザーバーノードが監視している条件を満たしたら、直下にあるタスクを中断する(※他の部分のツリーは継続される)。
[Brackboard Key]とは?>ブラックボード(データ保管庫)から特定のデータを取り出す鍵。
⑪敵の目(PawnSensing)を「BP_AI」内に追加
[BP_AI]のビューポート>左上[+Add]>[PawnSensing]を追加。
[Details]欄へ移り、[Peripheral Vision Angle]=[70]、[Sight Radius]=[500]に設定し、[Events]>[On See Pown]右の[+]ボタンをクリック。
▼[BP_AI]のイベントグラフを以下のように編集する。
- 移動速度が速い場合、[BP_AI]のビューポート>左上[Components]の[Character Movement]選択>右側[Details]の[Max Walk Speed]を450へ下げる。
これで「2秒ごとにランダム移動しつつ、プレイヤーを発見したら追尾して来る敵NPC」が実装できたはずだ!
◆ビヘイビアツリーの最終的な全体図
▲[BT_AI]のビヘイビアツリー完成図はこちら。
◆後でやりたい応用編
▲今回やった講座には続編(※追尾機能に加えて攻撃機能も追加するバージョン)があるようだから、また今度挑戦してみようと思う…!
▲2024年4月の無料アセット「ゴーレム」をボス敵として実装する続編動画もある。
忘れずに貰っておきたい!!