RecastNavigationを使ってナビゲーションAIを学習していく 3

# 初めに
　今回は第３回です。初めての人は[第一回](https://qiita.com/HnniTns/items/c76dcef212e36455b87e "https://qiita.com/HnniTns/items/c76dcef212e36455b87e")を見てください。今回は左ウィンドウのTool欄になります。
　この記事を見てくれている皆様に向けて注意点が一つがひとつ。注意して書いているつもりですが、間違ってる可能性が十分にあるのでその点だけ注意してください[^6]。

[第4回](https://qiita.com/HnniTns/items/8189beabbab3fe841ac6)を上げました。
追記: [第5回](https://qiita.com/HnniTns/items/aed13aa99f7a0310e2b1)を上げました。

[^6]: 流石に分かっていると思いますが、念の為書いておきます。

# エディタを見ていく（Tools欄(左ウィンドウ)）
## Test Navmesh
　これは名前の通りナビメッシュによる経路探索を行う項目になります。左クリックでゴール地点・右クリックでスタート地点を設定します。なぜかこのようにしたかは知りませんが、シフトを押しながらクリックすると問答無用でスタート地点の設定しかできません。
![01.01.Solo Test Navimesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/741077fa-01cb-26f8-9d42-8aede799fa80.png)


### ・Pathfind Follow
　経路探索を行いますが「Follow」と書かれている通り「スペースキー」を押す度に、スタート地点からゴール地点までを徐々に辿っていきます。
![Pathfind Follow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/705fb75e-7ba7-e1c8-bc03-ba3a01d79ef5.png)

### ・Pathfind Straight
　経路作成時に経路を綺麗にする設定（というよりは例？）です。
　「string pulling」アルゴリズムを実行している関数に影響しています。
　メッシュの中心（恐らく重心）に合わせて経路を作成すると、経路がおかしくなってしまうので、それを防ぐアルゴリズムです。下の図で説明すると、赤線から黄線にするアルゴリズムです。詳しい説明は[このサイト](http://digestingduck.blogspot.com/2010/03/simple-stupid-funnel-algorithm.html)で説明されています。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/92dc443e-3411-01ee-06de-9510445ea4c1.png)
※[画像元](https://pdfs.semanticscholar.org/1e92/858a275c37c0e2b94c3ad280014bf810f12e.pdf "https://pdfs.semanticscholar.org/1e92/858a275c37c0e2b94c3ad280014bf810f12e.pdf")

#### None
 Noneなので下のように起伏がある地形だと、まずめり込みます。
![Test Navimesh PathFind Straight None.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/2b76d760-b303-6518-6b2f-67ef44f37ce7.png)

#### Area
　正直なところ、「None」と変わっていない気がします。説明によると、「エリアが変わる場所で、全てのポリゴンの端に交差する頂点を追加します。[^3]」になっています。恐らく「エリアの端と経路が重なっている部分に頂点を追加する」という事です。
![Test Navimesh PathFind Straight Area.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/6e9d8134-1b2f-7d79-565f-13a1b1a0b6e1.png)
※頂点→<font color="Red">赤色の丸</font>　ポリゴンの端→<font color="Yellow">**黄色の丸**</font>

　ここでいうエリアというのが、よく分からないのですが、使う先を辿っていくと「各ポリゴンに割り当てられたエリアID」となっているので、恐らく「各ポリゴンをひとまとめにした**エリア**」の事だと思います。

例）
![Solo Poly Mesh Detail Text.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/067652ac-8450-4a23-329d-c6cdb4892311.png)
・ナビメッシュを構成するポリゴンは上図のようにねっていた場合
![Solo Poly Mesh Text.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/d3516724-110e-8fd5-169e-911648a718ab.png)
・それらをまとめたものを「ポリゴンエリア」からきていると思います[^2]。
※上図の数値は適当です

[^2]: 上図の「ポリゴンエリア」は長いので、「ポリエリア」と書いています。
[^3]: 圧倒的Google翻訳クオリティ...

#### All
　これが通常になると思います。説明によると、「ポリゴンのエッジが交差するたびに頂点を追加します。」となっています。恐らく「エリアの端・境目と経路が重なっている部分に頂点を追加する」という事です。
![Test Navimesh PathFind Straight All.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/f8f7efbe-7d6b-39cb-4c98-3303c1520230.png)
※頂点→<font color="Red">赤色の丸</font>　ポリゴンの端→<font color="Yellow">黄色の丸</font>　ポリゴンの端→<font color="Green">緑色の丸</font>

### ・Pathfind Sliced
　経路探索がどのように行われているかを視覚的に見えるようにしている機能です。ちなみに、NavMeshTesterToolでhandleUpdate関数を使っているのはこの機能のみです。
![Pathfind Sliced.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/378e5cf6-98ae-52c2-cc73-5d2160da57c8.gif)

### ・Distance to Wall
　一番近いナビメッシュの端までの距離と場所とベクトルを求める機能です。
![Distance to Wall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/3708c7d0-75e7-3e86-dacd-62baa8765c53.png)

### ・Raycast
　開始位置と終了位置間の[レイキャスト](https://qiita.com/4_mio_11/items/4b10c6fe37fd7a856350#:~:text=%E3%83%AC%E3%82%A4%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88%E3%81%A8%E3%81%AF%E3%81%82%E3%82%8B,%E5%A0%B4%E5%90%88%E3%81%AA%E3%81%A9%E3%81%AB%E7%94%A8%E3%81%84%E3%81%BE%E3%81%99%E3%80%82 "この記事を見ている人で分からない人はいないと思いますが、念の為に説明記事を載せておきます")を行う機能です。ゲーム次第ではよく使う機能になりそうです。
![Raycast.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/f9a6b234-6789-412c-1d85-de5553d71471.png)
　ただし、この関数は一つ注意点があり、説明にも書いているのですが、短距離用のXZ平面の2Dレイキャストになっています。その為、結果がおかしい事になることがあります。その代わりかなり高速に処理できます。
![Raycast2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/35a1df0c-47f4-239d-a5a5-86b33f2503b8.png "明らかに射線が通っていないにもかかわらず、レイキャスト成功判定になっています。")

### ・Find Polys in Circle
　[ダイクストラ法](http://www.deqnotes.net/acmicpc/dijkstra/)で円内のポリゴンエリア[^5]を検索する機能です。正確には、Start位置を基準にしたEnd位置までの円内に存在するポリゴンエリアをダイクストラ法で検索する機能になります。表示されている矢印は検索手順になっています。そして、これもXZ平面の2Dになっています。
![Find Polys in Circle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/b72063a1-ab19-7513-3e88-18980e48a993.png)

[^5]: RecastNavigation上の説明では「ナビゲーショングラフ」となっているのですが、ここでは「ポリゴンエリア」としておきます。

### ・Find Polys in shape
　[ダイクストラ法](http://www.deqnotes.net/acmicpc/dijkstra/)である形状内のポリゴンエリア[^5]を検索する機能です。正確には、Start位置を基準にしたEnd位置までの形状内に存在するポリゴンエリアをダイクストラ法で検索する機能になります。表示されている矢印は検索手順になっています。そして、これもXZ平面の2Dになっています。
　ちなみに「形状」は四角形になっていますが、内部的には変更可能です。
![Find Polys in shape.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/06d141b6-a8c3-61ff-9ab1-151ad251c364.png)

### ・Find Local Neighbourhood
　[ダイクストラ法](http://www.deqnotes.net/acmicpc/dijkstra/)で円内の重複しないポリゴンエリア[^5]を検索する機能です。「Find Polys in Circle」と似ていて、Start位置を基準にした円内に存在するポリゴンエリアをダイクストラ法で検索する機能になります。検索範囲はAgentのRadiusによって変化します。表示されている矢印は検索手順になっています。そして、これもXZ平面の2Dになっています。
　この方法は、検索半径が小さく、結果のポリゴン数が少ない場合に最適化されます。
![Find Local Neighbourhood.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/d4f60c01-9d73-5ac3-4363-318b5e924bb0.png)

### ・Set Random Start/Set Random End
　これは、名前の通りランダムにスタート地点とゴール地点を設置します。ただし、ゴール地点設置時はスタート地点と接続されているポリゴンエリア内のみ設置されます。

### ・Make Random Points
　これも、名前の通りナビメッシュ上に一定数のランダムなポイントを設置します。デモでは64個設置するようになっています。
![Make Random Points.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/166d05a3-872e-13fc-01ab-03d6b2163eb0.png)

### ・Make Random Points Around
　これは、スタート地点から一定範囲の円内に存在するポリゴンエリア上に一定数のランダムなポイントを設置します。これも同じく、デモでは64個設置するようになっています。
![Make Random Points Around.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/6e67a849-2afb-fcfc-66d2-24250f859778.png)

### ・Include Flags/Exclude Flags
　クエリフィルターの設定を行います。詳細は「[Create Convex Volumes](#create-convex-volumes)」で紹介します。

## Prune Navimesh
　これはナビメッシュの「選択・解除」を行う機能です。シンプルにそれだけの機能です。内部的な話になるのですが、「class NavmeshFlags」で選択されたかどうかの確認をしているみたいです。
![Prune Navmesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/c15c1e73-9203-8a74-11f0-82e4fc0852f9.png)

### ・Clear Selection
　全ての選択を解除します。正確には「class NavmeshFlags」の選択を解除します。

### ・Prune Unselected
　選択されていない全てのナビメッシュのフラグを解除します。正確にはnavmeshのsetPolyFlags関数でナビメッシュを無効化しています。

## Create Off-Mesh Connection
　接触していないナビメッシュ同士を**One Way（一方通行）**か**Bidirectional（双方向通行）**で接続します。
　注意点が一つ、ナビメッシュを再生成しないと適用されません。つまり動的ではないわけです。
![Create Off-Mesh Connection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/63f34953-2e35-c425-a660-e872c0a6b086.png)

## Create Convex Volumes
　読み込んだジオメトリに凸型形状を作成する機能で、経路探索に影響を及ぼします。この機能を使えば、このエリアは「海なので通さない」などの設定を可能にします。経路探索でいう「**コスト**」をどこに設定するかの機能になります。これも上記と同じようにナビメッシュを再生成しないと適用されないので注意が必要です。
　あと、凸型形状の確定には、形を確定したい時に最後クリックした頂点の場所をもう一度クリックする必要があります。
　この機能には数種類のタイプがあって、そのタイプによって経路探索に様々な影響が出ます。
![01.04.Solo Create Convex Volumes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/ff0980a8-4212-4793-9cd1-8a08a8a82d9d.png)

　コストの設定は別の場所で行っています。RecastNavigationでは凸型形状の各種類をコストと能力(機能)で切り離して扱っているので、通さない場合などはコストをバカ高くするのではなく、[Include Flags/Exclude Flags](#include-flagsexclude-flags)で能力(機能)の設定を行います。
![Create Convex Volumes text.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/9da5e53c-f22d-5a09-5149-267281d8f249.png)

<details><summary>内部の話</summary>
フラグ[^7]管理：Recast.h/class rcAreaModification
フラグ[^7]とナビメッシュの関連付け：Recast.h/rcMarkConvexPolyArea()
コストの設定：DetourNavMeshQuery.h/class dtQueryFilter/setAreaCost()
エリアの色を設定：Sample.h/class SampleDebugDraw/areaToCol()
</details>

[^7]: IDとマスク(ビット演算)で管理をしています。

### ・Shape Height
　凸型形状の高さの設定です。「ナビメッシュ表面にしか影響しないだろ」と思って適当に大きくしすぎないようにしてください。実はこの凸型形状内のナビメッシュ全てに影響するので、不意な形でナビメッシュに影響が出ます。
![Create Convex Volumes Height.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/1fb38f10-d9fb-ebfe-c93a-b153c3d560f7.png "凸型形状を高くしすぎたせいで上のナビメッシュにも影響が出る図")

### ・Shape Descent/Poly Offset
1. 凸型形状の位置を下げる設定です。
2. 凸型形状を外側に大きくするオフセット量の調整です。

## Create Crowds
　群衆AIを司る機能です。ある意味、RecastNavigationの最終形態です。少し特殊な操作の説明↓
1. スペース：動作の停止/続行
2. 数字キーの１：１フレームのみ続行
![01.05.Solo Create Crowds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/fbff3041-d27c-fd0f-7c91-d122860a3309.png)
※ 内部を見ていると所々で「neighbour」という単語が出てきますが、これは「付近のエージェント」のことです。

### ・Create Agents
　エージェント[^8]の設置と削除を行う機能です。削除はシフトを押しながら左クリックです。

[^8]: ここでいうエージェントとは、群衆内の一つという事です。つまり、エージェントをが集まったモノを「群衆」と解釈してください。にしても「Agent」の適切な日本語訳が思いつかない...。

### ・Move Target
　通常はエージェントの目的地を設定します。これはクリックした座標を目的地にします。
　シフトを押しながら左クリックor右クリックで、押した地点の方向へ向かって進みます[^9]。これは、「**各エージェント座標**から**押した瞬間の座標**へのベクトル」を決めて、目的地を決めません。

[^9]: 正直、あまり使わないと思いますが...。

### ・Select Agent
　エージェントを一体選びます。これを行うと、選択された一体のみを動かします。なお、これを行わないと「**[Selected Debug Draw](#selected-debug-draw)**」欄が適用されません。

### ・Toggle Polys
　エージェントが通過出来るポリゴンエリアの有効/無効を設定します[^10]。
　ただし、ポリゴンエリア上にエージェントが存在する場合に注意が必要です。基本は別のポリゴンエリアにかなりの速度で弾き出されますが[^11]、たまに、無効になったポリゴンエリアに残ったままのエージェントがいる事があります。こうなると、再び有効にしても全く動かなくなります。
　なので、無効にする際はそのポリゴンエリア上にエージェントが存在しない事を確認してから、無効にする必要がありそうです。

[^10]: 割と使える機能な気がします。
[^11]: この時点で、ゲームとしてはダメな気がしますね...。

### ・Options
#### 1.Optimize Visibility
　指定されたポイントがエージェントから見える場合、エージェントのパスの最適化を試みる機能です[^12]。
　不正確な移動[^13]or動的障害物回避[^14]は元のコライダーから大きく外側に位置を強制する可能性があり、時間経過で最適でないコライダーが形成される可能性があります。それにより最適でないパスが形成される事もあります。そういう場合にこの関数を使います。なお、エージェントの動きが不正確であるほどこの機能は有益になります。ただし、長距離検索の場合は適していません。
　結局、一言で言うと「次のポイントが直視出来たら、既存のパスよりも直接ポイントに向かって移動する方が良いじゃん」ということです。
　因みに、最適化された経路を表示するには、[Show Path Optimization](#5show-path-optimization)で表示可能です。

[^12]: 正直、見た目は変わっていない気がします。
[^13]: 恐らく、他のエージェントの移動による影響のことですね。
[^14]: これはどの事を指しているのか分からないのですが、Temp Obstaclesではないと思います。設置・削除する度にパスを再計算しているからですね。となると、どの事を指しているのでしょう？

#### 2.Optimize Topology
　ローカルエリアパス検索を使用して、エージェントのパスの最適化を試みる機能です[^12]。
　不正確な移動[^13]or動的障害物回避[^14]は、エージェントの位置をかなり外側に変更する可能性があり、時間経過で最適でないコライダーが形成される可能性があります。そういう場合にこの関数を使います。なお、エージェントの動きが不正確であるほどこの機能は有益になります。

#### 3.Anticipate Turns
　書いてある通り、エージェントの予想される回転方向をスムーズにする機能です。少なくとも、RecastNavigationでは「予想される回転方向と移動方向」も合わせて２回スムージングしていることになりますね。
　![Anticipate Turns Add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/01e547e8-e59d-bf19-9efd-4164e0d5f2e1.png "矢印が非常に見にくい事になっていたので、DrawをRaw Contoursに変更しています。")
※予想される回転方向→<font color="Blue">青色の丸</font>　移動方向→**黒色の丸**

![Anticipate-Turns-Add.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/86be591b-f64f-1fd6-783d-327cfd1b1e22.gif "違いを載せていますが、ほぼ変わらないという...。")

#### 4.Obstacle Avoidance
　これも名前の通り、障害物（付近のエージェント）を回避する機能です。ただ、これをオフにするだけでは「付近のエージェントを無視して進む」にはなりません。イメージとしては「回避する」から「重ならないようにする」という感じでしょうか。
![Obstacle Avoidance.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/ce1879cc-90ab-435c-a52a-c7038d97279c.gif)

#### 5.Avoidance Quality
　[上記](#4obstacle-avoidance)の回避具合を変更する機能です。これは、あらかじめ設定された「障害物回避パラメーター」の設定を変更します。初期化時にいくつかのパターンが設定されています。

<details><summary>内部の話</summary>
・障害物回避パラメーター：DetourObstacleAvoidance.h/struct dtObstacleAvoidanceParams
・設定場所：CrowdTool.cpp/void CrowdToolState::init()内
</details>

#### 6.Separation
　エージェント同士を分散[^15]させる機能です。
![Separation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/72398cf2-b166-d42e-7f8f-0f7226777faa.gif)

[^15]: Separationの辞書での意味は「分離・離別」なんですが、見た感じ どう見ても「分散」にしか見えないんです(笑)

#### 7.Separation Weight
　[上記](#6separation)の分離具合を変更する機能です。0にすると[上記](#6separation)をOFFにした時と変わらなくなります。

### ・Selected Debug Draw
　１体のみを対象とした、デバッグ描画欄です。[Select Agent](#select-agent)でエージェントを選択しないといけません。

#### 1.Show Corners
　エージェントが通る経路上の「角」を表示します。有効な（表示されている）コーナーは群衆AIの動作により「**最大コーナー数－1**」になります。

<details><summary>内部の話</summary>
・最大コーナー数：DetourCrowd.h/DT_CROWDAGENT_MAX_CORNERS
・群衆AI(マネージャー)の動作：DetourPathCorridor.h/class dtPathCorridor/int findCorners()
</details>
![Show Corners.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/ddb462a8-896a-b29c-de52-718a372a13a6.png "黒い点は分かり易いように描画しているだけなので、本当は描画されません。")

#### 2.Show Collision Segs
　円内・円上に存在する壁の境界線に描画します。円の半径は「ステアリング動作を開始する距離」になっています。なお、「エージェントの座標・セグメントの始点・終点」でナビメッシュ上に三角形を形状出来ない場合は、矢印の色が暗くなります。
　エージェントが通った後に存在するクロスポイントは、一定距離ごとに更新されます。

<details><summary>内部の話</summary>
・ステアリング動作を開始する距離：DetourCrowd.h/struct dtCrowdAgentParams/float collisionQueryRange
・セグメントを追加している場所：DetourLocalBoundary.h/class dtLocalBoundary/void update()
</details>
![Show Collision Segs Add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/6bed5a43-f044-ea9f-edac-e43c62fa1587.png "白い点は分かり易いように描画しているだけなので、本当は描画されません。")

#### 3.Show Path
　経路上に存在するポリゴンエリアを明るく描画します。
![Show Path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/863cf056-d020-586e-a256-63e5ac03de6f.png)

#### 4.Show VO
　これについては理解が微妙なんですが、恐らく、ペナルティーを四角形の色で描画したものだと思います。その為、円の半径が「エージェントの最大速度」になっています。ペナルティーの表現として**白がペナルティー無し**で、<font color="Red">赤色がペナルティー最大</font>です。
![Show VO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/3c45027c-e0f0-c4ae-410e-6442ed250396.png "他のエージェントのせいでペナルティーが増加している様子")

<details><summary>内部の話</summary>
　ペナルティーといっても、表示しているペナルティーは２種類あって、「合計ペナルティー」・「はみ出た分のペナルティー」になっています。色の表現は「合計ペナルティー：**白→最小**、<font color="Brown">茶色→最大</font>」、「はみ出た分のペナルティー：合計ペナルティーの色→最小、<font color="Red">赤色→最大</font>」になっています。
・ペナルティーの管理：DetourObstacleAvoidance.h/class dtObstacleAvoidanceDebugData
</details>
※余談ですが、「VO」って何の略ですかね？教えて詳しい人～。

#### 5.Show Path Optimization
　最適化された経路を表示します。正確には「エージェントの位置」から「[Optimize Visibility](#1optimize-visibility)で最適化された次の位置」になります。
![Show Path Optimaization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/0af04a98-4241-a858-ca1c-01afe3cee63e.png)

#### 6.Show Neighbours
　円内・円上に存在する「付近のエージェントの距離」と「付近のエージェントとエージェントまでの線」を描画します。円の半径は「ステアリング動作を開始する距離」で、「ステアリングを考慮する付近のエージェント最大数」分だけ表示します。

<details><summary>内部の話</summary>
・ステアリングを考慮する付近のエージェント最大数：DetourCrowd.h/DT_CROWDAGENT_MAX_NEIGHBOURS
・ステアリング動作を開始する距離：DetourCrowd.h/struct dtCrowdAgentParams/float collisionQueryRange
</details>
![Show Neighbours.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/ac761e3b-0640-89bd-231e-a0966b90d295.png "見やすいように色を変更しています")

### ・Debug Draw
　群衆AI全体のデバッグ表示を行う欄なので、特定のエージェントを選択する必要はありません。

#### 1.Show Labels
　これはエージェントを管理するラベルを表示します。ラベルというより配列の添え値なんですけどね。動的配列（初期化時にサイズを決めているので、実際のところ固定長配列みたいなもの）なんですが、添え値をキーにして、内部フラグのON/OFFで扱っています。動作だけ別で扱うので、こうなるのは仕方ないですね[^16]。

[^16]: もしくは連想配列を使うという手もありますが、なにせ、ランダムアクセス性能が...。ハッシュテーブルを使えばマシにはなりますが、速度を優先するなら、添え値をキーとして扱う事になると思います。（個人としては多少気になりますがね...。）

#### 2.Show Prox Grid
　エージェントの近接グリッドを表示します。これはエージェントがどれだけ「密」であるかを表しています。「密」であればあるほど濃くなっていきます。

![Show Prox Grid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/f3780225-f233-b4c3-d059-12439c3d711e.png)

#### 3.Show Nodes
　経路探索に使用したノードと[ヒューリスティックコスト](https://yttm-work.jp/algorithm/algorithm_0015.html "この記事を見てくれている皆さんなら分かると思いますが、念の為にA*の参考サイトを載せておきます。")を表示します。
　ON時は常に表示して欲しいのですが、「エージェント位置」から「物理的に接触していないポリゴンエリアの位置」に目的地を設置した時などにしか表示されません。その為、最初は「あれ？」となるので、注意して下さい。

![Show Nodes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/c6e38bc8-d741-f70c-3dd8-ddc52bdb434e.png)

#### 4.Show Perf Graph
　群衆AI全体の処理時間を表します。
![Show Perf Graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/339f20f9-74d0-5474-5a7e-85cd1025adee.png)

#### 5.Show Detail All
　[Selected Debug Draw](#selected-debug-draw)では選択したエージェントしか描画されませんでしたが、この項目をONにすると全てのエージェントに[Selected Debug Draw](#selected-debug-draw)の内容が描画されます。

## Create Tiles
　これはタイル毎にナビメッシュを生成・削除する機能です。正確には「Tile Mesh」・「Temp Obstacles」のナビメッシュ生成法によるもので、ナビメッシュ生成する際に分割し、「タイル」として生成しています。これが動的にナビメッシュを生成出来る秘密です。
　タイル上に左クリックでナビメッシュ生成、右クリックでナビメッシュ削除します。「Properties」欄の「Tiling」欄に「**TileSize**」があるので、そこでタイルサイズを変更出来ます。

![Create Tiles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/28de25b4-3630-da46-f7f3-c9045e4b557d.png)

### Create All
　全てのタイルを生成します。これは「Build」と同じです。

### Remove All
　全てのタイルを削除します。

## Highlight Tile Cache
　これはタイルの選択を行い、そのタイルの描画を変更する機能です。

# デモの問題点
　今回は中身編ではなく、デモの問題点を述べたいと思います。
1.メッシュ同士でまとめてナビメッシュを生成出来ない
2.~~「offmesh links」が「TileMesh/TempObstacle」上だと上手く機能しない事が多い~~ ※最新バージョンに更新したら治っていました。

・1 についてです。
![Unity Create NaviMesh Sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/999ec880-e6a0-a141-8c5a-045126e715c9.png "Unityのナビメッシュ")
![Demo Create NaviMesh Sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540257/4bbde195-9988-5db2-91b0-d11a5889b889.png "デモのナビメッシュ")
　上の画像を見てもらえれば分かると思うのですが、Unityではメッシュ同士を近づけたら、自動的にナビメッシュがマージされます。ですが、デモ版は少しいじった程度では自動的にマージされるわけがないので、マージするように自分でどうにかしないといけません。この機能はゲーム製作上、必要になることが多いかもしれないので皆さんもやりましょう[^4]。(｀･ω･´)

<details><summary>愚痴というか不満点なんで見なくてもOKです</summary>
1. 条件式でint型をbool値のように扱うのをやめてくれぇ～
2. ヌルを表すのに0を使うのはやめてくれぇ～、せめてNULLを使ってくれぇ～
以上。愚痴のような不満点でした（笑）
</details>

[^4]: ナビメッシュのマージ機能をデフォルトでつけてほしかったですねぇ...。PolyMeshとPolyMeshDetailはあるんですがね...。