【Unity】Navigationを使って経路探索させる


#概要

今回は以下のようなシンプルなプロジェクトを作り、Navigationの超基本的な使い方を学びます。

今回のプロジェクトでは、Unityちゃんがプレイヤー、赤いCubeが目的地になっています。

![Qiita4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/f7ea3781-cf8f-2481-07f0-cceb837ab1b6.gif)

【この記事の対象】　初中級程度の方

#Navigationとは？

UnityにはNavigatonという機能が搭載されています。

Navigationとはシーンのジオメトリから生成されるナビゲーションメッシュを使用して、ゲームの世界を知的に歩くことのできる機能です。
（Unity公式リファレンスより：[ナビゲーションと経路探索](https://docs.unity3d.com/jp/540/Manual/Navigation.html)）

今回は**NavMeshAgent**というコンポーネントを使ってNavigationを使っていきたいと思います。


#1．GameObjectを配置

まずは任意の場所にプレイヤー、目的地、障害物、地面を配置します。

<img width="426" alt="スクリーンショット 2019-12-14 11.54.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/429f6866-0c20-a680-cfac-f816295dd84f.png">


今回はそれぞれのGameObjectに


| 種類       　      　　|       名前 |
|:--------------------|:----------:|
| プレイヤー(Unityちゃん) |Player      | 
| 目的地(Red)           |Destination |
| 障害物(Green)         |Obstacle |
| 地面(White)           |Ground      |
という名前をつけました！

#2．NavMeshAgentをつける

次に今回の記事の要であるComponentの**NavMeshAgent**をつけていきます。

NavMeshAgentは経路探索をして、動いて欲しいObjectにアタッチします。
今回のプロジェクトでは**Player**にアタッチします。

<img width="317" alt="スクリーンショット 2019-12-14 10.51.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/8ed16bec-3270-60dd-923e-4a7eec00b4c4.png">

#3．Playerのスクリプトを書く

次にPlayerのスクリプトを書いていきます。

```PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class PlayerController : MonoBehaviour
{
    NavMeshAgent Player_Nav;
    GameObject Destination;

    void Start()
    {
        //プレイヤーのNavMeshAgentを取得
        Player_Nav = GetComponent<NavMeshAgent>();
        //目的地のオブジェクトを取得
        Destination = GameObject.Find("Destination");
    }

    void Update()
    {
        //目的地を設定
        Player_Nav.SetDestination(Destination.transform.position);
    }
}
```

ポイントは

　　　１．**名前空間**に`using UnityEngine.AI`を記入しているか
　　　２．Playerの**NavMeshAgent**をきちんと取得できているか
　　　３．`SetDestination`をきちんと書いている（目的地の指定ができている）

の３点です！！

#4．NavigationWindowを開く

次にPlayerが行動できる範囲を指定するために、NavigationWindowを開きます。
![navigationwindow.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/35fb2ae2-eba4-8060-60e0-3c8488e36fcf.gif)



#5．移動範囲をBakeする

それではPlayerの移動範囲を指定していきましょう。

Ground、Obstacleを選択し、Inspectorビュー内のStaticの横にある三角をクリックし、**Navigation Static**を選択します。


![About Static.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/8458d19d-0ef3-f9a7-c18f-d25cb614b100.gif)

次に歩かせる範囲と歩かせない範囲を指定します。

範囲の指定にはNavigationWindowのObjectの**Navigation Area**の部分をいじっていきます。

|Navigation Area|機能|
|:--------------|:-----:|
|Walkable|選択したエリアが歩けるようになる|
|Not Walkable|選択したエリアが歩けないようになる|
|Jump|auto-generated、Off-Mesh Links の際に利用する(今回は使用しません)|

<img width="324" alt="スクリーンショット 2019-12-14 12.12.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/06596af3-3fdc-80a6-9658-42b9fc635e48.png">

今回のプロジェクトにおいて歩かせる範囲はGround、歩かせない範囲はObstacleにあたるので、
Groundを**Walkable**に、Obstacleを**Not Walkable**に設定します。

以上の設定が完了したら、NavigationビューBakeの右下にある**Bake**をクリックして移動範囲の指定を完了させます。

![Bake3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/aab9a611-0342-a369-e0f4-677ab3cc0cfb.gif)

上の画像のように、移動範囲が青く表示されたら完了です！！！

#6．動かしてみる

以上の設定が終わったらプレビューボタンを押してみましょう。

![Preview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541729/b5cf7074-1df4-16ff-f5a1-87cd01a0d721.gif)

PlayerのUnityちゃんが自動で経路探索し、指定範囲の上を歩きましたね！！
これでNavigation機能を使うことができました！！

#最後に

いかがだったでしょうか？

Navigation機能はこんなに簡単に実装できてしまうんです。

次回の記事ではNavigation機能を使用して、動く障害物を避ける方法をご紹介したいと思います。