【UE5】プレイヤーを追いかける最小のAI

ナビメッシュを使ってパス検索しつつ、プレイヤーを追いかけるだけのAIを作ろうとしたのですが、

「最低限何をすれば良いのか?」

…という情報は、調べても出てきませんでした。

調査しながら試行錯誤して、動作するものを作成。
そこから不要な部分を削ることで、

「何が必要なのか?それは何故必要なのか?」

…が分かりましたので、本稿で共有したいと思います。

本稿は初心者向けです。
C++ は使用せず、ブループリントを使用します。

動作環境
UE 5.4 と 5.3.2
Windows 11 Home

作業の流れ

プロジェクトを作る

ナビメッシュを作る

ブラックボードを作る

タスクを作る

ビヘイビアツリーを作る

AIController を作る

キャラクターを作る

動作確認

この順番で説明します。

プロジェクトを作る

※クリックまたはタップすると拡大表示します。

「サードパーソン」でプロジェクトを作成します。

※クリックまたはタップすると拡大表示します。

プロジェクトを作成すると、上図のようなスプラッシュ画面が表示されるので、消えるまで待ちます。

※クリックまたはタップすると拡大表示します。

スプラッシュ画面が消えると、上図のようなエディタが起動します。

※クリックまたはタップすると拡大表示します。

プロジェクト作成直後なら、ThirdPersonMap がレベルビューポートに表示された状態になっていると思います。

もし、ThirdPersonMap じゃない場合は、「コンテンツブラウザ」または「コンテンツドロワー」で、以下の順番にフォルダをたどることで、ThirdPersonMap レベルがあるフォルダに到達できるので、ダブルクリックしてロードしてください。
All > コンテンツ > ThirdPerson > Maps > ThirdPersonMap レベル

ナビメッシュを作る

AIを使ってキャラクターを移動させる場合、以下の2つの方法があります。

1. ナビメッシュの中だけ移動させる。
2. ナビメッシュ関係なく指定した位置に移動させる。

今回は 1. を行うため、ナビメッシュを作る必要があります。

もし、「アウトライナー」の中に「NavMeshBoundsVolume」がある場合は、この手順は行わず、次へ進んでください。
「NavMeshBoundsVolume」がない場合は、上図の通りに「ナビメッシュバウンズボリューム」を選択します。

※クリックまたはタップすると拡大表示します。

レベルビューポートにオレンジ色のワイヤーフレームキューブが追加され、「アウトライナー」に「NavMeshBoundsVolume」が追加されます。
※既に「NavMeshBoundsVolume」がある場合は、気にせず次へ進んでください。

※クリックまたはタップすると拡大表示します。

アウトライナーの「NavMeshBoundsVolume」を左クリックで選択し、「位置」と「拡大・縮小」を変更します。
おおまかに上図のような状態になればOKです。

メニューの「ビルド」→「パスをビルド」を選択します。
これで ThirdPersonMap にナビメッシュが生成されます。

※クリックまたはタップすると拡大表示します。

レベルビューポートの何もないところを左クリックして、キーボードの「P」キーを押し、上図のような緑色に塗られたナビメッシュが表示されるのを確認します。
AI にナビメッシュの中を移動させる場合、この緑色の中だけを移動します。

ナビメッシュが表示されない場合、以下を確認します。
・マウスの左ボタンクリックが反応するか。
・キーボードの P キーが反応するか。
・UE エディタがフリーズしていないか。
・レベルビューポート内にある壁や床など、何らかのオブジェクトを選択していないか。
・アウトライナーにあるフォルダやオブジェクトを選択していないか。
・アウトライナーにある NavMeshBoundsVolume を削除し、ナビメッシュを作り直して表示されるか。
・UE エディタを再起動した後、表示されるか。

ブラックボードを作る


ブラックボードはAIが覚えておくためのデータです。
このデータは、AIが色々な状況判断をするときに使います。
今回必要になるデータは、追いかける対象(プレイヤー)がいる位置(座標)になります。

※クリックまたはタップすると拡大表示します。

「コンテンツブラウザ」または「コンテンツドロワー」の「+追加」ボタンを左クリックして、AI > ブラックボード を選択します。

ブラックボードのアセットが作られるので、適当な名前を入力します。
今回は「BB_Test」にしました。

※クリックまたはタップすると拡大表示します。

作成したブラックボードのアセットをダブルクリックすると、ブラックボードの編集ウィンドウが表示されます。
その中にある「新規キー」を左クリックして、候補の中から Vector を選びます。

※クリックまたはタップすると拡大表示します。

ブラックボードに Vector 型のキーが追加されるので、名前を「PlayerLocation」に変更します。

タスクを作る

タスクは AI の小さな行動目標です。
プレイヤーを追いかけるだけの AI には、以下のタスクが必要です。

1. プレイヤーの位置を覚える。
2. 覚えた位置に移動する(ナビメッシュ使用)。

このふたつのタスクのうち、2. は UE 側に用意されているので、自分で作る必要はありません。
作るのは 1. だけです。

※クリックまたはタップすると拡大表示します。

「コンテンツブラウザ」または「コンテンツドロワー」の「+追加」ボタンを左クリックして、一覧から「ブループリントクラス」を選びます。

※クリックまたはタップすると拡大表示します。

上図のように、「すべてのクラス」を左クリックすると、その下にテキストボックスが表示されるので、「task」と入力します。
テキストボックスの下に、task が含まれるクラスの候補が表示されるので、その中から「BTTask_BlueprintBase」を選びます。


ブループリントクラスのアセットが新規作成されるので、アセット名を入力します。
とりあえず、「BTTask_SetPlayerLocation」にしました。

※クリックまたはタップすると拡大表示します。

作成したブループリントクラスのアセットをダブルクリックすると、ブループリントの編集画面が表示されます。


「マイブループリント」内、「変数」の右側にある「+」アイコンを左クリックします。
「NewVar」という名前の変数が追加されるので、名前の右側にある変数の型名「Boolean」を左クリックします。
(Boolean ではない場合があるかも知れませんが、デフォルトの型は使わないので何でも構いません。)

変数名の候補が表示されるので、テキストボックスに「black」と入力し、候補を絞ります。
候補を絞ると、上の方に「Blackboard Key Selector」が表示されるようになるので、それを選択します。


変数の型を設定したら、変数名を変更します。

「NewVar」を左クリックすると、変数名を変更できるようになるので、「BlackboardKey」に変更します。
(変数名は任意です。NewVar のままでも構いません。)

設定が終わると、上図の状態になります。

このブループリント変数は、別のファイル(ビヘイビアツリーとブラックボード)からアクセスします。
デフォルトの状態では、別のファイルからアクセスできないので、アクセスできるようにします。


変数の型の右隣にあるアイコンを左クリックします。

このアイコンは、まぶたを閉じた状態(外から見えない=外から見えないので外からアクセスできない状態)を意味しています。
「外」というのは、このアセットの外部、このアセットではない別のファイルのことです。


上図のように目が開いた状態にします。
これで別のファイルから、この変数にアクセスできるようになります。


「コンパイル」ボタンを押してコンパイルします。
※ここで一度コンパイルしないと、追加した変数をブループリントで使うことができません。

※クリックまたはタップすると拡大表示します。

上図のように、「イベントグラフ」の何もない所を「右クリック」します。
イベントグラフに配置できるノードの候補が表示されるので、テキストボックスに「event recei」と入力して候補を絞ります。
絞った候補の中から「Event Receive Execute AI」を選択します。

※クリックまたはタップすると拡大表示します。

AI がこのタスクを処理するとき、このイベントから処理が始まります。

※クリックまたはタップすると拡大表示します。

変数 BlackboardKey をイベントグラフにドラッグ&ドロップします。
候補から Get BlackboardKey を選択します。


イベントグラフに配置した BlackboardKey の右端にある青い丸 を左マウスボタンを押しながら、何もないところにドラッグすると、イベントグラフに配置できるノードの候補が表示されます。
候補の AI カテゴリーにある Set Blackboard Value as Vector を選択します。

これは AI に Vector 型の値を覚えてもらうための処理です。
この値にプレイヤーの位置(座標)をセットすることで、AI はプレイヤーの位置を覚えることができます。


上図のようになります。


上図のように、ノードの右端・左端についている、横向きの三角形を左マウスボタンでドラッグして、接続したいノードの三角形にドロップします。
この線を繋ぐことで、イベントノードから処理が開始し、線が繋がっている順番にノードが処理されます。


この場合、Event Receive Execute AI ⇒ Set Blackboard Value as Vector の順番に処理されます。

※クリックまたはタップすると拡大表示します。

あとは右クリックのイベントグラフに配置できるノードの候補から、上図にあるノードを選び、ブループリントの処理を作成します。

追加で配置するノードは以下です。
GetPlayerPawn
GetActorLocation
FinishExecute


「コンパイル」ボタンを押してコンパイルします。

ビヘイビアツリーを作る

ビヘイビアツリーは AI の行動を組み立てるフローチャートのようなものです。

ここまでで作成した「ブラックボード」と「タスク」は、ビヘイビアツリーで使うためのものです。

プレイヤーを追いかけるだけの AI には以下のふたつのタスクが必要です。

1. プレイヤーの位置を覚える。
2. 覚えた位置に移動する(ナビメッシュ使用)。

1. ⇒ 2. の順にタスクを処理して、2. のタスクが終わったら、また 1. に戻ります。
やるべきことはそれだけで、それを「ビヘイビアツリー」の仕組みに合わせて組み立てます。

「コンテンツブラウザ」か「コンテンツドロワー」の「+追加」ボタンを押して、AI > ビヘイビアツリー を選びます。

ビヘイビアツリーのアセットが作られるので、アセット名を入力します。

ここでは「BT_Test」にしました。


作成したアセットをダブルクリックすると、ビヘイビアツリーの編集ウィンドウが表示されます。


「詳細」ウィンドウの AI > BehaviorTree > Blackboard Asset に「BB_Test」が設定されていない場合は、設定します。
※既に設定されている場合は、この手順は不要なので、次のステップへ進んでください。
※BB_Test は「ブラックボードを作る」で作成したものです。


「Root」ノードの下部に、黒に近い灰色の矩形がくっついていますが、ここでマウスの左ボタンを押しっぱなしにして、そのまま「Root」ノードの外へドラッグします。
そうすることで、この矩形から白い矢印が伸びるので、何もないところにドロップします。


配置できるノードの候補が表示されるので、「Sequence」を選びます。

ここで Sequence を選んだ理由は、冒頭で説明した以下の処理を行うためです。

1. ⇒ 2. の順にタスクを処理して、2. のタスクが終わったら、また 1. に戻ります。

なので、Sequence は2つのタスクを持つことになります。

「Sequence」ノードを配置するときと同じように操作して、ノードの候補から「BTTask Set Player Location」を選びます。
※「BTTask Set Player Location」は「タスクを作る」で作成したものです。

Sequence の下にタスクが追加されました。
これが冒頭で説明した 1. のタスクになります。

1. プレイヤーの位置を覚える。
2. 覚えた位置に移動する(ナビメッシュ使用)。

追加したタスクを左クリックして選択した状態にします。
タスクのフチがオレンジ色になっていれば、選択した状態になっています。
この状態で「詳細」を見ます。

デフォルト > Blackboard Key が SelfActor になっていたら、PlayerLocation に変更します。
これによって、このタスクはブラックボードの PlayerLocation に値をセットできるようになります。
SelfActor のままだと、タスクがうまく処理されません。

タスクの「詳細」で設定した「Blackboard Key」は、「タスクを作る」でブループリントに追加した Blackboard Key Selector 型の変数「BlackboardKey」と対応しています。

タスク 1. を作成したので、タスク 2. を作成します。

1. プレイヤーの位置を覚える。
2. 覚えた位置に移動する(ナビメッシュ使用)。

※クリックまたはタップすると拡大表示します。

タスク 1. と同様に操作を行い、候補から Move To を選びます。

Move To は UE 側に用意されているタスクです。
指定した位置に向かって、ナビメッシュの上を移動してくれます。
パス検索も勝手にやってくれます。


Move To ノードを左クリックして選択した状態にして、「詳細」のブラックボード > Blackboard Key > を「PlayerLocation」に変更します。

こうすることで、

BTTask_SetPlayerLocation タスクでプレイヤーの位置が PlayerLocation に入る。

Move To タスクで PlayerLocation に入っている位置まで移動する。

という順番で処理が行われるようになります。

AI Controller を作る

ここまでで、「プレイヤーを追いかけるだけの AI」の処理は完成しましたが、その AI を呼び出す方法がまだありません。
脳はあるけど、体がない状態です。

AI(ビヘイビアツリー)を呼び出すには、以下のものが必要です。

1. AI を使うキャラクター
2. AI とキャラクターを結びつけるコントローラー

ここでは、2. を作る方法について説明します。

「AI とキャラクターを結びつけるコントローラー」は、
そのまま「AI Controller(AI コントローラー)」と呼びます。

AI コントローラーもブループリントで作ることができます。

ブループリントを新規作成する方法は、ここまでのステップで既に説明しているので省略します。


ブループリントの親クラスは AIController にします。


アセット名は「BP_TestAIController」にしました。

「BP_TestAIController」をダブルクリックしてブループリントの編集ウィンドウを表示します。


「イベントグラフ」に切り替え、「Begin Play」と「Run Behavior Tree」ノードを繋げます。


「Run Behavior Tree」の BTAsset で作成したビヘイビアツリー(BT_Test)を選択します。


ブループリントをコンパイルします。

この AI コントローラーを、AI を走らせたいキャラクターに組み込むことで、ビヘイビアツリーが処理されるようになります。

キャラクターを作る

AI コントローラーを組み込むキャラクターを作成します。


サードパーソンテンプレートには、ゲーム実行時のプレイヤーキャラクターが既に用意されているので、とりあえず、これを使います。
と言っても、そのまま使うわけではないので、順を追って説明します。

ブループリントを新規作成する方法は、ここまでのステップで既に説明しているので省略します。


ブループリントの親クラスは「BP_ThirdPersonCharacter」にします。


アセット名は「BP_TestCharacter」にしました。

※クリックまたはタップすると拡大表示します。

「BP_TestCharacter」をダブルクリックして編集ウィンドウを開きます。


「詳細」 > ポーン > AI Controller Class を「BP_TestAIController」に変更します。
※「BP_TestAIController」は「AIController を作る」で作成したものです。


コンパイルします。

これで作成したビヘイビアツリーを処理する AI コントローラーをキャラクターに組み込むことができました。
あとは、このキャラクターをレベルに配置すれば動作を確認できるようになります。

※クリックまたはタップすると拡大表示します。

作成した「BP_TestCharacter」をレベル内にドラッグ&ドロップします。
ドロップする位置は床がある場所ならどこでも構いません。


位置関係はこんな感じですが、図の通りにする必要はありません。

図中の「AI キャラクターのカメラ」は「BP_TestCharacter」にくっついているものです。
このカメラは親クラスの「BP_ThirdPersonCharacter」が持っているものなので削除できません。
カメラを持たないキャラクターを作りたい場合は、BP_ThirdPersonCharacter を複製して、カメラを削除し、それを親に設定します。


UE エディタがクラッシュする前に保存しておきます。

UE5 になってから頻度は減りましたが、何か変更したらすぐに保存する癖をつけておいた方が良いです。

動作確認


レベルビューポートの上部にある再生ボタンを押すことで、動作確認できます。


こちらはアイキャッチ画像で使用しているアニメーション GIF の加工元ロングバージョンです。

複雑なことは何もしていませんが、こんな AI を作れてしまいます。

EQS を使わないのは何故?

今回は、プレイヤーの位置をブラックボードに保存する部分をタスクで実装しましたが、Environment Query System (EQS) でも同じことができます。
ただ、EQS は UE 5.4 の時点ではβ版なのでお勧めはしません。

本稿で使用している画像のいくつかは、以下のサイトからダウンロードしたものです。

https://illpop.com/
https://www.irasutoya.com/

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です