【UE4】ナビゲーションシステムのSupportedAgentsについて

# 注意
:::note warn

2016年時点での内容なので、現在のUE4のバージョンとは整合性が取れていない箇所があります。@mizuki_izuna さんがUE4.27での記事を書いてくださったので、こちらの記事は話半分程度で読んでください。
:::

[SupportedAgentsで大きさの違うキャラそれぞれに合わせたナビメッシュで動かす話 by @mizuki_izuna](https://qiita.com/mizuki_izuna/items/99a874ab14f214d7f36d#_reference-76ea3c1d6e130384e72f)

#はじめに
最近GTA4を遊んでいて「歩行者は歩道を歩き、車は車道を走る」ようにNavMeshを設定出来ないだろうかと思い、色々調べた結果プロジェクト設定にある「Supported Agents」が「AIごとに使用するNavMeshを設定する」役割を担っているようですので、そのSupportedAgentsについて解説しようと思います。



#Supported Agents
Supported Agentsは上でも書きましたが「どのNavMeshがどのようなエージェント（AI）に対して歩行可能なエリアとして情報を提供するか」を定義出来る設定項目です。

この設定項目ですが
ウィンドウ＞プロジェクト設定＞エンジン＞ナビゲーションシステム＞Agents
にあります。
![1_設定項目場所.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/4a587b20-d786-dec2-29d4-9b67469edd64.png)

#Supported Agentsの定義
では、実際にSupportedAgentsを設定していきます。使用するテンプレートプロジェクトは「Top Down テンプレート」です。
＋ボタンを押してエレメントを２個追加します。
設定項目がたくさん出ますが変更箇所は「Name」「Color」「Nav Agent Radius」「Nav Agent Height」「Can Jump」「Can Walk」「Can Swim」の７つです。
以下のように項目を変更します。
![2_エレメント追加.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/9fdb901d-bddb-fe1e-c860-a26ae70b8348.png)

図のTypeAで設定しているNav Agent RadiusとNav Agent Heightですが、この値はブループリント「TopDownCharacter」にある「CapsuleComponent」の「Capsule Half Heightを２倍した数」と「カプセル半径」です。これを基準のサイズとします。

|||
|:-:|:-:|
|![3_カプセルコリジョン.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/bc40891e-c1de-3338-6c4c-7b4c621f6e3d.png)|![4_コリジョンサイズ.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/b6a1ebfe-0bf4-16d6-0586-3eddd7d22c2a.png)

TypeBはTypeAのNav Agent Radiusを半分にした値です。Nav Agent HeightはTypeAと同じです。
これらの設定によりNavMeshがサポートするエージェントは２種類になりました。

#レベル上にNavMeshを敷く
次にレベル上にNavMeshを敷き、それぞれのエージェントを割り当てます。
TopDownExampleMapに既に配置されているNav Mesh Bounds Volumeと新しく追加したボリュームを配置します。
それぞれのボリュームのサイズは適当でOKです。以下の画像ではわかりやすくするため、わざと２つのボリュームをちょっとだけ重ねています。

||
|:-:|
|![5_レベル上にNavMesh.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/536986e8-5ada-25a8-215f-34af6a0958ff.png)

では配置したNavMeshBoundsVolumeに対してエージェントの設定をします。
どちらかのボリュームを選択して、詳細パネルの項目「Navigation」にあるチェックボックスをTypeAかTypeBのどちらかにチェックを入れるだけです。設定出来たら、もう片方のボリュームにも同様の設定をします。エージェントのタイプは逆にしてください。
![6_NavMeshBoundsVolumeにエージェントを設定.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/e4d6819e-c903-7848-9ebd-79b8e5c1e025.png)
この設定により、どのエージェントに対しNavMesh情報を提供するかを決定出来ます。

設定が終わり、実行してみるとTypeAに設定したNavMeshの範囲では移動が可能ですが、TypeBに設定したNavMeshの範囲では移動が出来ないようになっているはずです。

#TopDownCharacterのMovement Capabilityを変更する
今度はTopDownCharacterのMovement Capability設定を変更してTypeAは移動不可にしてTypeBを移動できるようにします。
ブループリント「TopDownCharacter」を開き、コンポーネント「CharacterMovement」を選択します。
詳細パネル内にある「Movement Capability」を探して、NavAgentRadiusをTypeBで設定した値に変更します。
![7_TopDownCharacterの設定を変更.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/75347e8a-108b-4565-f006-90f77f6c5d14.png)

#Movement Componentの設定を変更する
次にMovement Capabilityに設定した値を使用するようにMovement Componentの「Update Nav Agent With Owners Collision」のチェックを外します。
![8_コリジョン設定を使わない.PNG](https://qiita-image-store.s3.amazonaws.com/0/104467/f4c97761-27b8-0f9a-f1d4-7b9703e621ad.png)
この項目にチェックが入っていた場合、Movement CapabilityのNav Agent RadiusとNav Agent HeightにはCapsuleComponentのHalf Heightと半径の値が自動で入ってしまいます。

これらの設定によりTypeBに設定したNavMeshでの移動が可能となるはずです。

#AIが参照するNavMeshを決める基準
キャラクターのMovement Capabilityの値を変更することにより、それぞれのエージェントタイプが設定されたNavMeshでの移動が可能となりましたが、この選択基準は「各設定項目に合致するエージェントタイプが設定されているかどうか」と思われます
[Answer Hubより](https://answers.unrealengine.com/questions/104881/how-do-i-associate-my-character-with-a-navigation.html)
今回の記事の場合だとナビゲーションシステム設定で設定した「Nav Agent Radius」と「Can Jump」「Can Walk」「Can Swim」とTopDownCharacterのMovement Capabilityの「Nav Agent Radius」と「Can Jump」「Can Walk」「Can Swim」が基準点となります。
TopDownCharacterのRadiusをSupported Agentsで設定した値よりも大きく離した値にすると両方とも参照できなくなります。

#まとめ
Supported Agentsが未設定の場合、全てのAIはレベルに存在するNavMesh上の移動が可能となりますが、適切な設定をすることにより移動範囲や移動経路をある程度制御出来ます。これによりGTAのような「歩行者は歩道を歩く。車は車道を走る」であったり「狭い道は小型の敵だけ通れる。広い道は小型も大型も通れる」というような表現も可能となります。