NavmeshAgentを使用した敵の追跡 & 近くまで敵の追跡

敵がついてくる範囲の設定

![スライド6.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/f508cccb-5fd4-18e2-4346-93cf55b35ff5.png)

NavMeshAgentの追加と設定
![スライド7.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/b2ebb04d-5ba2-094a-bea6-5bdb5e75f0c0.png)
![スライド8.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/bed4e038-09e1-db4b-497a-3e61a2b7d06d.png)

敵が主人公を追いかけるスクリプトの作成

```EnemyFollowPlayer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyFollowPlayer : MonoBehaviour {

    public GameObject target;
    NavMeshAgent agent;
    // Use this for initialization
    void Start () {
        agent = GetComponent<NavMeshAgent>();
	}
	
	// Update is called once per frame
	void Update () {
        agent.destination = target.transform.position;
	}
}
```

スクリプトを貼り付けるオブジェクト：プレイヤーについてこさせたい敵

TargetにプレイヤーをD&D
![スライド9.PNG](https://qiita-image-store.s3.amazonaws.com/0/214359/ea939768-e6f0-62af-4bdb-d48489a14b4f.png)

主人公を敵が追跡します
![nav.gif](https://qiita-image-store.s3.amazonaws.com/0/214359/66259dd3-6511-c6da-639f-e958c88f1992.gif)

敵を主人公の近くで止めたい場合はこっちを入力して貼り付ける


```EnemyFollowPlayer.cs
using UnityEngine;
using System.Collections;

public class EnemyFollowPlayer : MonoBehaviour
{
    public Transform target;
    UnityEngine.AI.NavMeshAgent agent;

    float myCollisionRadius;
    float targetCollisionRadius;

    [Range(1.0f, 10.0f)]
    public float attackDistanceThreshold = 1.0f;

    float nextAttackTime;
    // 1 second.
    float timeBetweenAttacks = 1;

    void Start()
    {
        agent = GetComponent<UnityEngine.AI.NavMeshAgent>();

        myCollisionRadius = GetComponent<CapsuleCollider>().radius;
        targetCollisionRadius = target.GetComponent<CapsuleCollider>().radius;

        StartCoroutine(UpdatePath());
    }

    void Update()
    {
        // Time.timeはゲーム開始からの秒。
        if (Time.time > nextAttackTime)
        {
            
            // 距離を比較するときは、平方根(Mathf.Sqrt)のコストが高いので、距離の二乗通しを計算することで、パフォーマンスをあげる。
            // 現在のターゲットと自身の距離の二乗。
            float sqrMag = (target.position - transform.position).sqrMagnitude;
            // 攻撃開始の閾値の二乗
            float sqrAttackRange = Mathf.Pow(myCollisionRadius + targetCollisionRadius + attackDistanceThreshold, 2);
            if (sqrMag < sqrAttackRange)
            {
                nextAttackTime = Time.time + timeBetweenAttacks;
                Debug.Log("Attack");
            }
        }
    }

    IEnumerator UpdatePath()
    {
        while (target != null)
        {
            // ターゲットの中心にまで移動する
            //Vector3 targetPosition = new Vector3(target.position.x, 0f, target.position.z);
            //agent.SetDestination(targetPosition);

            // 方向を求める
            Vector3 directionToTarget = (target.position - transform.position).normalized;
            // directionToTarget * (自分の半径+ターゲットの半径)で、自分とターゲットの半径の長さ分の向きベクトルが求められる。
            // つまり、元々のターゲット座標から、この長さのベクトルを引けば、ターゲットに重ならない。また、マージンとしてattackDistanceThresholdを用意している。
            // これはoffsetでもpaddingでもmarginでもどんな変数でもよくて、とりあえず、敵の攻撃範囲としている。
            Vector3 targetPosition = target.position - directionToTarget * (myCollisionRadius + targetCollisionRadius + attackDistanceThreshold / 2);
            agent.SetDestination(targetPosition);


            // １秒ウェイト
            yield return new WaitForSeconds(.5f);
        }
    }
}
```

![nav追加.png](https://qiita-image-store.s3.amazonaws.com/0/214359/cfa51073-459b-21f2-edef-1dfd078f17ad.png)

主人公の近くで止まります
![nav追加.gif](https://qiita-image-store.s3.amazonaws.com/0/214359/44ade10a-645b-ab03-83f6-d50aed9c7db1.gif)


[目次に戻る](https://qiita.com/takasaki19841121/items/55daf89bbd2e0998a16c)