[UE4] ナビゲーション機能を提供するクラス-2

検証バージョン: UE4.26.0
　本記事ではランタイムでナビゲーション機能を提供するオブジェクトについて紹介します。

# Core
## Navigation System
　ナビゲーションシステムを統括するオブジェクトです。UE4.26の時点ではUNavigationSystemV1が主要な機能全般を担っているため、プロジェクトで使用する場合はV1を継承したクラスの利用をお勧めします。NavigationSystemはワールド毎に1つ存在し、World Settingsからプロジェクトのカスタムクラスを設定することが可能です。
![2020-12-18_16h46_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/88096b6c-a9fd-84f4-564f-8b7c0b14fe37.png)

　詳細な設定項目については[Project Settings](https://qiita.com/EGJ-Ken_Kuwano/private/c1facb6014f67cf323e6#navigation-system)をご参考ください。

## Navigation Query Filter
　パス検索時に特定のエリアを除外するためのフィルターの機能を持つクラスです。図のようなケースにおいて、A-1⇒A-2はフィルタリングされないため直線パス、B-1⇒B-2は特定のエリアをフィルタリングすることによって迂回パスとなります。このように、特定のクラスをパス検索などに含めたくない時には、特定のエリアクラスをフィルターに登録して利用します。
![2020-12-18_16h46_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/4d9bc821-27fb-f1af-b446-f87c951ee9a4.png)
　以下の方法によって除外したいエリアクラスを登録するだけで利用することができます。

**[簡単な使い方]**
① Navigation Query Filterを親クラスとしてクラスを作成
② 作成したクラスを開いてフィルタリング対象のエリアを設定
③ 続けてIs Excluded = trueに設定
④ フィルタリングしたい対象にクラス設定 (AIController, パス検索等)

　以下の図はフィルターに除外するクラスを設定する内容を示します。
![2020-12-18_16h47_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/8272510b-0fc7-6849-5402-5fa574e13f78.png)

## Navigation Path
　ナビゲーション機能で扱うパス情報のクラスです。パス長, パス進行コスト, Way Pointsなどの情報を持つため、具体的に抽出されたパスから経路などを知ることもできます。以下図のようにBlueprintからのアクセスも可能で、デバッグ情報などを取得することもできます。
![2020-12-18_16h48_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/9bbfbb6f-87cc-ed75-5911-3988648de092.png)

## Navigation Octree
　ナビメッシュを高速に構築するために作成される、ワールド上のジオメトリ情報を持つオブジェクトクラスです。ユーザーが直接Octreeを操作することはありませんが、ナビゲーションシステムはワールド上に投入されたコリジョンを検出してナビメッシュの構築や、動的な変更エリアを検出するために利用されます。
　以下の図はRecastNavmeshのデバッグ描画によってOctreeがフォーカスするオブジェクトを可視化したものです。
![2020-12-18_16h48_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/916f5e3c-8594-9137-8b90-fa517d85b084.png)

## Navigation Grid Path
　特別なパス検索を行う領域を作成して、領域を迂回するようなパスを提供するクラスです (Experimental)。パス検索対象が領域外にある場合は通常のパス検索を行い、パス検索対象が領域内にある場合は領域を迂回したいようなケースにおいて利用することができます。以下図のようにVisualLoggerで可視化するとグリッドデータを表示することができます。Navigation Grid Pathには専用で制御を担っているGridManagerクラスが存在しています。
![2020-12-18_16h48_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/3c19b1bf-67a3-c029-7c2d-b516bb9c36a5.png)
![2020-12-18_16h49_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/c99da46c-63c5-6c31-ba05-1aebce2535ca.png)
　以下で示すように、専用のAIControllerとGridを追加するだけで利用することができます。Controllerが迂回するための領域（Grid）はGridDataが対象となり、Data自体は任意に追加する必要があります。

**[簡単な使い方]**
① AIControllerに”Grid Path AI Controller (または継承クラス)”を選択
② Grid Path Following Componentが自動的に連携して動作
![2020-12-18_16h50_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/253aadc9-cf93-fcd2-587a-512a72a8fbce.png)

## Nav Area
　ナビメッシュに対してArea(属性)を設定することができるオブジェクトクラスです。ナビメッシュバウンスが生成された領域上に配置することで、ボリュームの範囲に対して独自の進行条件や重み付けを設定することが可能です。
　以下はナビエリアの重みづけや、デバッグ表示の色、サポート対象のエージェントなど、クラス独自の動作を規定することができます。
![2020-12-18_16h55_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/8cebd2de-7546-4c43-7fd4-2bb9cf23eeab.png)
　Area Classにはコストの概念がありますが、これは経路探索に影響を及ぼします。Area Classを設定することでナビメッシュに影響を及ぼして経路探索の結果も変わります。以下はエンジンで定義されているデフォルトのクラス一覧です。
![2020-12-18_16h51_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/06b01def-3a74-ebc7-9e60-2cc059402f4d.png)

|項目|説明|
|:--|:--|
|NavArea_Default (なし)|通行可能なエリア<br>Navmesh Bounds Volumeで代用が可能|
|NavArea_LowHeight (青色)|進行不可なエリア(コスト値は固定、独自機能を所有)<br>エージェントが進行できない高さのエリアを明示的に示す際に有効|
|NavArea_Null (Navmesh生成なし)|進行不可なエリア (コスト値は固定)<br>進行不可エリアを明示的に示す際に有効|
|NavArea_Obstacle (茶色)|高コストエリア (コスト値は固定)<br>進行は可能だがパス検索優先度が低いエリアを定義する際に有効|

　以降でデフォルトのエリアについて説明を記載します。
#### Obstacle：高コスト（障害）エリア
　下の図は橋の上からPlayerに接近するエージェントの様子ですが、一般的には最短経路であるルート①が選択されます。しかし、ルート①には進行経路に高コストエリア(NavArea_Obstacle:茶色)が配置されているため、進行コストが高いことから最終的にはルート②の経路を選択してプレイヤーに向かってきます。もしルート②の経路に進行不能エリア(NavArea_Null)が存在してパスを形成できない場合は、たとえルート①の進行コストが高くともルート①を選択することになります。これがコストによる重みづけと、高コストエリアでの挙動となります。
![2020-12-18_16h54_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/6ad474d3-9d52-3e89-c4af-6b688a8c28e9.png)

#### Low Height：進行不可エリア
　独自の用途としてはエージェントが進行不可能な高さを明示的に示すのに利用します。Low Height Areaに対してのみ適用される機能も存在します (Recast Nav Meshの項参照)。
![2020-12-18_16h56_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/a1a3fbcb-3ffc-d5ee-e284-4c48ff2eeb0c.png)

#### Switch By Agent：スイッチエリア
　エージェント毎にArea Classを指定可能なエリアです。下記図中央のNav Modifier Volumeはエージェントの領域内に指定したエリアの属性を適用することができます。Agent1の領域はAgent0AreaのDefault、Agent2の領域はAgent1AreaのNullが適用される動作となります。
![2020-12-18_16h57_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/b9a682f9-1325-1946-dc7f-271f03a263c9.png)

## Crowd Manager
　これに関する詳細は、[[UE4] CrowdManagerによる群衆の制御](https://qiita.com/EGJ-Ken_Kuwano/items/120901d259467568e4f7)をご参考ください。

主だったクラスは以上となりますが、他に役立ちそうなものがあれば追加したいと思います。