[Unity 2D] NavMeshPlusでターゲットを追跡する敵を作る


# １. NavMeshPlusをインポート

まずは以下のリポジトリからzipをダウンロードしてください。
* 「Code」を選択し、「Download ZIP」を選択するとダウンロードできます

https://github.com/h8man/NavMeshPlus

<br>
ダウンロード完了後、各フォルダ<strong>「Gizmos」</strong><strong>「NavMeshComponents」</strong>をプロジェクトのAssets配下にインポートしてください。<br>
インポート後、Unityのパッケージマネージャーから<strong>「AI Navigation」</strong>をインストールしてください。

![00AI Navi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/5532c4c0-34f5-46ce-b47d-f2d976434e35.png)

# ２. NavMeshを生成

簡単にステージを作成します。
* 四角形の2Dオブジェクトで地面(歩行可能なスペース)とブロック(歩行不可なスペース)を作成
* ターゲット(赤)と敵(青)のオブジェクトを作成

![01stage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/49c386ee-5a0e-4122-bab5-4f15a140ec0a.png)

<br>
地面とブロックにコンポーネント<strong>「Navigation Modifier」</strong>をアタッチし、<strong>override area</strong>にチェックを入れます。
地面は<strong>Walkable</strong>、ブロックは<strong>Not Walkable</strong>を選択です。

![02ground.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/3db0ce2a-5291-4c91-99b6-386de119f186.png)

![03block.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/ed974517-a31e-4f15-bc95-5038d180735c.png)

:::note info
ブロックのコンポーネントは<strong>「Nav Mesh Obstacle」</strong>でもいいですが、ベイクでNavMeshを生成したときに、角が角ばってしまったり、動的に移動させたいわけではないので、「Navigation Modifier」にしてあります。
:::

<br>
[任意] window -> AI -> Navigationを選択し、新しくAgent typeを作成。

![04agent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/3248527d-f912-42cc-96f8-20081fc811cd.png)

<br>
空のオブジェクトを作成し、各コンポーネント<strong>「Navigation Surface」「Navigation CollectSources2d」</strong>をアタッチ。<br>
Agent typeIDに先ほど作成したAgent typeを設定。

![05navmesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/a8128223-c49d-4daf-abe3-9796bbb6ec40.png)

<br>
「Navigation CollectSources2d」の<strong>Rotate Surface to XY</strong>を１回だけ実行します。
実行すると、オブジェクトのRotationXが-90になり、2Dでベイクができるようになります。<br>
後は「Navigation Surface」のベイクを実行でNavMeshが生成され、青色の道が表示されるはずです。

![beak.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/7daa7c56-8ee9-435f-9309-3cf78c70c9fc.png)

# 追跡をさせてみる
先ほど作成したターゲットのオブジェクトに以下のスクリプトを作成してアタッチします。
```ruby:qiita.rb
using UnityEngine;

public class Target : MonoBehaviour
{
    void Update()
    {
        var mousePos = Input.mousePosition;
        var pos = Camera.main.ScreenToWorldPoint(mousePos);
        transform.position = new Vector2(pos.x, pos.y);
    }
}
```

<br>
<br>
次に敵のオブジェクトに各コンポーネント<strong>「Nav Mesh Agent」「Circle Collider 2D」</strong>をアタッチ
「Nav Mesh Agent」の半径を「Circle Collider 2D」の半径に揃えてください。

![06enemy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/d0f8962e-8dac-446c-bcdf-82016cdfcbf5.png)

<br>
続いてターゲットを追跡するスクリプトを作成し、敵のオブジェクトにアタッチします。

```ruby:qiita.rb
using UnityEngine;
using UnityEngine.AI;

public class Enemy : MonoBehaviour
{
    [SerializeField] Transform target;
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.updateRotation = false;
        agent.updateUpAxis = false;
    }

    void Update()
    {
        agent.destination = target.position;
    }

    void OnDrawGizmos()
    {
        if(!agent || !agent.enabled) return;
        Gizmos.color = Color.red;
        Vector2 startPos = transform.position;
        foreach (var endPos in agent.path.corners)
        {
            Gizmos.DrawLine(startPos, endPos);
            startPos = endPos;
        }
    }
}
```
:::note info
OnDrawGizmosは省略可能
:::

作成が完了したら、targetの変数にターゲットのオブジェクトを設定して完了です。
実行してみるとマウスカーソルに向かって敵が追跡してくるようになります。

![hoge.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4094218/e767c46e-38e0-4aad-9e30-f5fe0bc54b6f.gif)


# ３. 他にサイズが異なる敵を作成したい場合

* 新しくAgent typeを作成し、半径を調整します
* NavMeshを作成したオブジェクトを複製し、対象のAgent typeIDを変更後、ベイクを実行します
* あとはNavMeshAgentに作成したAgent typeを設定するのを忘れないで下さい