【Unity】AIが賢く移動できるための機能、NavMeshとオフメッシュリンクを設定する

# 最初に

本記事はUnityでのNavMeshとオフメッシュに関して解説した記事となります。

# NavMeshとは？

ゲーム内に設置してあるジオメトリから、**自動で生成される簡略化された地形の表面**です。これのおかげによって、AIを持つキャラクターに**障害物を避けて通るような知的な移動を行わせること**が可能となります。

このNavMeshは`NavMeshSurface`という高レベルなNavMeshコンポーネントを使用することで**ランタイムでも更新することが可能**なので、扉が開くなどのステージギミックがあった際にもNavMeshの繋がり部分を気にせず自由に作成することができます。

ちなみにこのNavMeshに沿って移動を行うキャラクターのことを**ナビメッシュエージェント(NavMesh Agent)**と呼びます。

NavMeshを用いた経路検索アルゴリズムはUnityではA*を採用しているようです。

## NavMeshの生成

Unityのメニューから[Windows]→[AI]→[Navigation]と進んでください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/4d82809f-aae5-f59a-5e16-89786f302a34.png)

Inspector部にNavigationタブが表示されたと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/4ba5a6a7-d8e6-5b1c-0276-29f9804ed1ab.png)
最初にシーン中の静的オブジェクトを示してBakeしてみましょう。

「Navigation Static」というチェックボックスをtrueにしてください。

次に[Bake]タブを開いてNavMeshを生成するのに必要なプロパティ群を確認していきましょう。

|設定名|概要|
|----|----|
|Agent Radius|キャラクターの中心が壁などにどの程度まで近づけるか|
|Agent Height|キャラクターの手が届く高さ|
|Max Slope|キャラクターが登れる傾斜角度|
|Step Height|キャラクターが登れる段の高さ|

蒸気をキャラクターのサイズに合わせて調整しましょう。

調整した後はBakeボタンを押下することで、NavMeshが作成できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/1b72b63c-b47e-c35d-2a05-1b5fea70162c.png)

青色になっている箇所がNavMeshが作成されていることを表しています。

作成後はAssetsフォルダ下の同シーンが格納されているフォルダ内にシーンと同名のフォルダが作成されているはずです。そのフォルダ下にNavMesh.assetが作成されます。

## 高レベルなNavMesh

Unityが用意しているNavMeshにはいくつか高度なNavMeshも存在しています。これらは**Unity標準には含まれておらず**、自身で[Unity Technologies GitHub](https://github.com/Unity-Technologies/NavMeshComponents)からDLしてインストールを行う必要があります。

↓公式の詳細ページ↓
https://docs.unity3d.com/ja/2018.1/Manual/NavMesh-BuildingComponents.html

この辺はまた改めて試して記事を書いてみようと思います。

# オフメッシュリンクとは？

**オフメッシュリンク(Off-Mesh Link)**は歩行する以外での移動組み込みを可能にしてくれます。たとえば障害物を飛び越えさせて**移動のショートカットを行わせる**時に、このオフメッシュリンクが役立ちます。

では早速作成してみましょう。

## オフメッシュリンクの手動作成

まず最初なのでGameObjectから任意のジオメトリを二つ用意してシーンのショートカットのStart位置とEnd位置の場所に設置してください。実際にゲームに組み込む際には**空のGameObjectでも問題ありません**。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/033da92b-8180-ff36-8025-72e126bfa39d.png)

ショートカットを開始する場所に設置したら、Start側のオブジェクトに**Navigation > Off Mesh Link**というコンポーネントを追加します。

そのコンポーネントの設定にStartとEndがあるので、それぞれ設置したジオメトリをアタッチしてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/8df7c07a-29b1-90d8-e6d8-06b1b79c2173.png)

NavMeshがすでにBakeされていればオフメッシュリンクも有効となります。

適用されていない場合は、アタッチした後にNavMeshをBakeすることでオフメッシュリンクも適用されます。

## オフメッシュリンクの自動生成

オフメッシュリンクはNavMeshと同様にBake時の設定で自動生成することも可能です。

まず、NavigationタブのObjectタブを確認しましょう。

ここにある「Generate OffMeshLinks」というチェックボックスをtrueに設定してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/5d0cbaa4-0003-bbda-b329-614885f76315.png)

その後、Bakeタブに戻り、オフメッシュリンクの自動生成に必要な設定をさらに行いましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/2255d15e-047e-171a-fb5a-b2c0dc721c81.png)

|設定名|概要|
|----|----|
|Drop Height|落下を行う高さの最高値|
|Jump Distance|ジャンプを行う最長距離値|

どちらも**値を0に設定することでオフメッシュリンクは生成されなくなります**。

値の適正な数値は公式マニュアルを参考にしてみてください。↓
https://docs.unity3d.com/ja/2018.1/Manual/nav-BuildingOffMeshLinksAutomatically.html

ここまで設定できたらBakeを押下してみてください。以下のようにオフメッシュリンクが自動で生成されたのを確認できたと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/7bc7c8bb-147b-2dec-097f-f4e168790281.png)

# 最後に
オフメッシュリンクの存在を知らなかったため、こんな便利機能があることに感動しました。さすがUnity、つよい。そのうちハイレベルなNavMeshも試して動かしてみたいと思います。

# 参考

- [Unity 公式リファレンス](https://docs.unity3d.com/ja/2018.1/Manual/Navigation.html)
- UnityによるVRアプリケーション開発(書籍)