UE4で敵キャラクターAIを制御する

敵キャラクターを動かすAIを実装するため、ビヘイビアツリーの機能を使ってみたいと思います。最終的にプレイヤーキャラを発見したら追跡し、見失ったら元居た場所に戻るという動作を目指します。
※画像はクリックで拡大できます
ビヘイビアツリーとは
イベント駆動型のアーキテクチャで、ツリー状に条件式やタスク、イベントを登録して動作させて行く事で視覚的に見やすく、デバックもし易いので使いこなせれば凄く便利そうな機能です。
ビヘイビアツリーによる敵のAI実装は公式ドキュメント、「ビヘイビアツリーのクイックスタートガイド」を追っていく形で実装してみます。
また、敵キャラが発見する自プレイヤーや、マップのNavMeshBoundsVolumeの設置等は前回の記事で準備した物を使用します。
AI制御に必要な物の準備
ビヘイビアツリーによる敵AI制御に必要な物は主に、以下の4つです。この4つをコンテンツプラウザにまず新規追加します。
Characterクラス
ブループリントクラス→Characterで追加できます。敵のキャラクター用のCharacterブループリントクラスです。敵キャラ用メッシュのセットや、CapsuleComponentの形状調整、CharacterMovementによる動作の設定、中でも詳細のPawn項目にある、AI Controller Classにこれから作成するAIControllerを設定する事が大事です。自分は「Enemy1」という名前の物を作成しました。
AIControllerクラス
ブループリントクラス→検索にAIControllerと打つと出てきます。CharacterクラスのPawn項目にある、AI Controller Classにセットします。AIControllerのイベントグラフで、使用するブラックボードやビヘイビアツリーの登録や、ブラックボードで使用するキーに値をセットしたりします。「EnemyController」という名前のAIControllerクラスを作成しました。
ブラックボード
AI→ブラックボードで追加できます。ブラックボード中に変数のようにして使用するキーを追加できます。このキーの値をビヘイビアーツリー上で参照して、条件式で分岐したり判別に使用したりします。また、ブループリントでキー名を指定して値をセットしたりできます。「EnemyBlackboard」という名前で作成しました。
ビヘイビアツリー
AI→ビヘイビアツリーで追加できます。サービス、タスク、デコレーター等で制御を実装し、SelectorやSequenceでブラックボードのキー値を見て条件分岐をして行く事で、ツリー状に制御を構成する事ができます。ゲームを動作させながら、ツリーの動作を見る事もできるのでデバックにも重宝します。
Characterクラスの実装
とりあえず最初に、敵キャラクターのCharacterクラスを実装していきます。
コンポーネントのMeshに敵キャラ用のMeshをセットし、向きをArrowComponentに合わせて、CapsuleComponentの形状をMeshに合わせて調整し、CharacterMovementのOrient Rotation to Movementにチェックを入れて移動方向にキャラが回転するようにする、といういつもの一連の設定を行います。
今回で大事な設定なのが、Pawn項目にあるAI Controller Classに作成したAIControllerクラスを設定する事です。
ブラックボードの実装
ブラックボードにキーを追加する事で、ビヘイビアツリーがキー値を見て条件分岐したり、ビヘイビアツリーから追加する事ができる「サービス」、「タスク」、「デコレーター」のブループリントでキー値をセットしたりできます。
「新規キー」追加ボタンを押して、下記の三つのキーを追加します。
TargetToFollow
KeyTypeをObjectに設定します。敵キャラクターが追跡するターゲットとして対象のActorを確保するためのキーです。
HomeLocation
KeyTypeをVectorに設定します。敵キャラクターの初期座標を確保するためのキーです。敵キャラが戻る時に必要になります。
TargetLocation
KeyTypeをVectorに設定します。敵キャラクターが追跡するターゲットの座標確保用です。
AIControllerの実装
Characterクラスに設定したAIControllerを実装していきます。イベントグラフにブループリントを記述していきます。
変数「HomeLocation」を作成し、デフォルト値をHomeLocationにします。
ブループリントは下記画像のようにします。
やってる事は使用するブラックボードのセット、ブラックボートのキー値「HomeLocation」に初期座標セット、使用するビヘイビアツリーの実行です。
ビヘイビアツリーの実装
AIControllerのブループリントでセットしたビヘイビアツリーを実装していきます。
サービスの実装
ビヘイビアツリーをダブルクリックして開いたら、「新規サービス」をクリックしてブループリントクラスを作成します。名前は「AgroCheck」にしました。
AgroCheckのイベントグラフを開き、下記画像の通り変数を用意します。
AgroCheckのブループリントを下記画像のように実装します。今回の肝となる制御部分なので長くなっております。画像を分割しております。
やってる事に関しては、「MultiSphereTraceForObjects」で球形の指定範囲で自分以外のAIControllerを持つActorを探索し、「LineTraceByCnannel」で自分から対象Actorにレイを飛ばしてレイが対象Actorにぶつかれば対象Actorのオブジェクトと座標をブラックボードのキー値に伝えています。
タスクの実装
「新規タスク」をクリックしてブループリントクラスを作成します。名前は「RapidMoveTo」にしました。
RapidMoveToのイベントグラフを開き、下記画像の通り変数を用意します。
RapidMoveToのブループリントを下記画像のように実装します。
ブラックボードのキー値、Target to Followに指定されているターゲットの座標に向けて移動する処理です。
デコレーターの実装
「新規デコレーター」をクリックしてブループリントクラスを作成します。名前は「CloseEnough」にしました。
CloseEnoughのイベントグラフを開き、下記画像の通り変数を用意します。
CloseEnoughのブループリントを下記画像のように実装します。
自分とターゲットとの距離を、Acceptable Distanceと比較して追跡を続けるか終了するかを判定する処理です。
ビヘイビアツリーの組み立て
これまでに用意したサービス、タスク、デコレーターを用いてビヘイビアツリーを下記画像のようにします。
SelectorやSequence、RapidMoveTo等は右クリックして検索欄に入力すれば出てくるので容易に設置できます。
AgroCheckはSelectorを右クリックして、「サービスを追加」の欄内にあります。Blackboardや他の物に関しても、SelectorないしSequenceを右クリックして「デコレーターを追加」の検索欄に入力すれば出てきます。
①~⑩までの詳細を、下記画像のように設定します。
敵キャラクターを配置して実行してみる
これまでの実装で、敵キャラクターが自キャラクターを発見したら追跡し、見失ったら元の位置に戻るようになっているはずなので実行してみます。
で、結果ですが確かに自キャラクターの追跡と見失ったら引き返すという挙動をしてくれましたが、一つ気になる所が出てきました。
公式ドキュメントの通りだと、AgroCheckのMultiSphereTraceForObjectsで指定するRadiusの範囲外で、自キャラクターを見失う事ができません。
そのため、敵キャラクターの探知範囲を狭めたいと思いRadius値を小さく調整すると自キャラクターを見失う処理に行かず、ひたすら追跡してきます(汗
なのでAgroCheckのMultiSphereTraceForObjectsの次の処理にちょっと変更を加えます。次の画像の通りです。
MultiSphereTraceForObjectsとForEachLoopWithBreakの間に、探知オブジェクトが無かった場合にTarget To Followのオブジェクトをクリアする処理を追加しました。
これで探知範囲外に出た時、敵キャラクターは元の位置に帰るようになります。
長くなりましたが、この状態で動作させてみます。
敵が追跡と探知外で戻る行動をちゃんとしました!
ディスカッション
コメント一覧
はじめまして。こちらの記事をみながらAIを実装することができました。わかりやすい解説で、とても助かっています!
しかし、この方法で実装した場合、ほかに徘徊する敵キャラなどがいた場合そちらについて行ってしまうということが起こりました。
もし解決法などご存じでしたらお教えいただけませんでしょうか??よろしくお願いいたします。
こちらで紹介している記事では、「AI MoveTo」のTarget ActoreにプレイヤーのActoreをセットしている事でプレイヤーのみを追跡するようになっています。意図していないキャラクターを追跡した際のTarget Actoreの内容をウォッチしてみるのが良いかもしれません!