LoginSignup
7
12

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-11-16

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

スライド6.PNG

NavMeshAgentの追加と設定
スライド7.PNG
スライド8.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

主人公を敵が追跡します
nav.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);


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

nav追加.png

主人公の近くで止まります
nav追加.gif

目次に戻る

7
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
12