Navigationで迷路からの脱出


https://docs.unity3d.com/jp/540/Manual/nav-NavigationSystem.html

## 歩行可能なルートをつくる

NavMesh
https://docs.unity3d.com/jp/540/Manual/nav-BuildingNavMesh.html

壁と地面をStatic状態にする
Window > Navigation > Bake でベイクする

![スクリーンショット 2017-10-07 6.22.11.png](https://qiita-image-store.s3.amazonaws.com/0/136286/ffb34e7c-cc96-c9ee-7406-fcd9346ca7c0.png "スクリーンショット 2017-10-07 6.22.11.png")


## キャラを動かす設定

NavMesh Agent
https://docs.unity3d.com/jp/540/Manual/nav-CreateNavMeshAgent.html

NavMeshAgentのプロパティ
https://docs.unity3d.com/jp/540/Manual/class-NavMeshAgent.html

目標地点の取得
`navAgent.destination = targetPos`
or
`navAgent.setDestionation(targetPos)`
https://docs.unity3d.com/jp/540/ScriptReference/NavMeshAgent.SetDestination.html

```c:MyNavAgent.cs（キャラにアタッチする）
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyNavAgent : MonoBehaviour {

    private UnityEngine.AI.NavMeshAgent navAgent;
    private Animator animator;
    private Vector3 lastPoint;
    private GameObject goal;

    void Start () {
        navAgent = GetComponent<UnityEngine.AI.NavMeshAgent>();
        animator = GetComponent<Animator>();
        lastPoint = transform.position;
		goal = GameObject.Find("Goal");
    }

	void Update () {
		if(Input.GetMouseButtonDown(0)){
			// カメラからクリックした地点までのレイ
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
			if(Physics.Raycast(ray, out hit, 1000)){
				// クリックした地点に向かう
                navAgent.destination = hit.point;
				// ゴール地点を表示
            	goal.GetComponent<Goal>().SetLoc(navAgent.destination);
            }
        }
		// スピードの測定
		float dist = Vector3.Distance(lastPoint, transform.position) * (1 / Time.deltaTime / navAgent.speed);
        lastPoint = transform.position;
		// AnimatorコンポーネントのControllerをダブルクリックしてParametersから確認
		animator.SetFloat("Forward", dist);
    }
}
```

ゴール地点に球を出現させる

```c:Goal.cs（ゴールのオブジェクトにアタッチする）
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Goal : MonoBehaviour {

    private UnityEngine.AI.NavMeshAgent navAgent;
    private Renderer myRenderer;
    private GameObject t;

    void Start () {
        t = GameObject.Find("ThirdPersonController");
        navAgent = t.GetComponent<UnityEngine.AI.NavMeshAgent>();
        myRenderer = GetComponent<Renderer>();
        myRenderer.enabled = false;
    }

	void Update () {
		if(myRenderer.enabled){
			if(Vector3.Distance(t.transform.position,transform.position) < 2){
				// 近づいたら見えないところに飛ばす
                transform.position = new Vector3(10000, 0, -10000);
				myRenderer.enabled = false;
            }
		}
	}

	public void SetLoc(Vector3 _p){
		// ゴール地点にセット
        transform.position = new Vector3(_p.x, 1, _p.z);
		myRenderer.enabled = true;
    }
}
```

## 動く障害物を置く

NavMesh Obstacle
https://docs.unity3d.com/jp/540/Manual/class-NavMeshObstacle.html

### Carveにチェックを入れない

障害物がなくなるまで待つ

![obstacle.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/f426d625-1608-4a26-a307-cff75ab47cff.gif "obstacle.gif")

### Carveにチェックを入れる

障害物を避けて別ルートを選択する
（計算負荷が高い）

![curve.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/eac28d19-e609-a8da-e765-f5007a73b825.gif "curve.gif")