執筆バージョン: Unreal Engine 4.12
改訂バージョン: Unreal Engine 4.19 |
今回はEQSという機能を使って群れを動かすのをやってみようと思います。
この機能は4.12ではまだ実験的機能として提供されている段階なので、記事の内容は将来的に使えなくなる可能性があります。
EQSとは、複数の選択肢の中から条件に合わせた、最も良いActorや場所(Vector)などを求めてくれる機能です。
条件にはキャラクターから見えるか、キャラクターの正面にあるか、近いか、などの条件が複数設定できます。
EQSの公式ドキュメントはこちら
Environment Query System
https://docs.unrealengine.com/ja/InteractiveExperiences/ArtificialIntelligence/EQS/EQSOverview/index.html
Behavior Treeはこちらを参考にしてください
ビヘイビアツリー
https://docs.unrealengine.com/ja/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreesOverview/index.html
1.EQSの機能をOnにする
「編集 > エディタの環境設定」からエディタの環境設定を開き、「一般 > 実験段階」のAI内にあるEnvironment Query SystemのチェックボックスをONにするとEQSが使えるようになる。

2.Behavior Treeの準備
コンテンツブラウザ上で右クリックをし、AIの項目から「ビヘイビアツリー」と「ブラックボード」を作成する。
AIで動かすキャラをCharacterを親にして作成、さらにAIControllerを親にしてブループリントを作成する。

Characterのブループリントを開き、デフォルト値のPawnの中にあるAIControllerClassに先ほど作成したAIControllerのクラスを設定。

次にAIControllerのブループリントを開きEventGraphのBeginPlayからUseBlackboardとRunBehaviorTreeノードをつなぎ、それぞれに先ほど作ったアセットを設定。

これでBehaviorTreeの機能を使う準備ができました。
3.EQSの準備
コンテンツブラウザから右クリックでAIの項目にある「環境クエリ」を選択します。これがEQSの本体となります。

4.EQSで探すActorを作成
今回はネコちゃんが餌に群がるようなQIを作りたいので、エサとなるブループリントをActor継承で作成します。
StarterContentから適当に拝借し、こんなブループリントになりました。

CollisionはコリジョンプリセットをOverlapAllDynamicに設定しています。
5.EQSの作成
環境クエリのアセットをダブルクリックで開きます。
ダブルクリックで開くと「ルート」のみ表示された状態です。
まずは、右クリックから”Generator”を作成します。詳しい種類については、公式のリファレンスをご覧ください。 https://docs.unrealengine.com/ja/InteractiveExperiences/ArtificialIntelligence/EQS/EQSNodeReference/index.html
この中からActor of Classを選択します。
Searched Actor Classに先ほどのBP_Foodを設定します。半径には5000としておきます。
これで範囲内のBP_Foodクラスを返すEQSとなります。
このままでは、発見したBP_Foodクラスに優劣がつかないのでActorOfClassノードを右クリックして「テストを追加」から条件を付けていきます。
一つ目はDistanceを設定します。
これは距離により優劣をつける条件です。
パラメータは以下のようにします。

これで距離の近いものほど選ばれやすくなります。
二つ目の条件にPathExistを選択します。
これは、対象までの移動経路が確保できるかどうかを評価します。
これで、到達できない位置にいるActorを省くことができます。
パラメータは以下の通りです。

これでEQSは完成です。

6.Behavior TreeでEQSを使う
まず、ブラックボードを開き「新規キー」でObjectを作成します。

BaseClassにはActorを設定します。ここでは名前をFoodとします。
EQSは最も良いとみなした結果をActorか場所(Vector)で求め、BlackBoardのキーに返してくれます。そのためBaseClassにはActorかVectorを設定してください。
次にビヘイビアツリーを開きます。
BlackboardAssetには先ほどのブラックボードを設定します。
SimpleParallelノードを配置し、SimpleParallelノードを右クリックで「サービスを追加… > Run EQS」を選択します。
パラメータは以下の通りです。

狙ったFoodが存在するかどうかを新規タスクを作って監視します。
上の新規タスクから「BTTask_BlueprintBase」を選択し、タスクを作成します。名前はExistとしました。
BlackboardKeySelector変数を作成し、編集可能にしておきます。

コードは以下の通りです。

対象のActorがなかった場合、FinishExecuteにて失敗を返します。
このタスクと、BehaviorTreeのデフォルトのタスクである「MoveTo」を使い以下のようにBehaviorTreeを作成しました。

ExistとMoveToのタスクはそれぞれ対象となるActorを設定できるので、それぞれにブラックボードで用意したFoodを設定します。
7.NavMeshボリュームを配置する
EQSで設定したAIを動かすため、Modes (モード) -> Volume (ボリューム) -> Nav Mesh Bounds Volumeをマップへドラッグして配置します。

AI Characterを移動させたい領域を囲むように配置してください。

以上で一番良いご飯に向かうネコちゃんのAIの完成です。

右クリックで餌を置く。
おなかが減ると小さくなっていき消える。
満腹になると3つに分裂する。
などの要素を入れるとこんな感じになりました。