unity3d WayPoint路点寻路,AI

前言

一个简单的人工智能WayPoint
WayPoint: 游戏中敌人根据几个巡逻点自动巡逻,在巡逻过程中,时刻监听英雄(敌人)和自己距离是否达到追击范围(不巡逻,追击英雄),在追击过程中,监听是否达到攻击范围(不追击,攻击)。

所需对象

  1. 当前玩家
  2. 敌人
  3. 3个巡逻点
    1

每个对象的脚本

2

脚本类

1.巡逻点 ,这里给每个巡逻点添加这个类,并拖入这个巡逻点的下一个巡逻点

public class WayPoint : MonoBehaviour {
    public WayPoint NextWayPoint;
}

2.控制玩家移动脚本

public class PlayerMove : MonoBehaviour {

    void Update () {

        float h = Input.GetAxis ("Horizontal"); //x轴 ad
        float v = Input.GetAxis ("Vertical");//z轴 ws

        transform.Translate (h * Time.deltaTime * 2, 0, 0);
        transform.Translate (0, 0, v * Time.deltaTime * 2);
    }
}

3.敌人巡逻AI,发现玩家就追击玩家,到一定距离攻击

using UnityEngine;
using System.Collections;
/// <summary>
/// Enemy AI.
/// 敌人的AI,
/// 1. 3个点之间的巡逻
/// 2. 追击,攻击英雄
/// </summary>
public class EnemyAI : MonoBehaviour {

    public WayPoint _startWayPoint;
    WayPoint _targetWayPoint;

    public GameObject _playerPoint;
    GameObject _targetPoint;

    void Start(){

        _startWayPoint = GameObject.Find ("WayPoint1").GetComponent<WayPoint> ();
        _playerPoint = GameObject.Find ("Player");

        Vector3 v = _startWayPoint.transform.position;
        // < 某值,根据实际值计算
        if (Vector3.Distance (v, transform.position) < 0.5f) {
            _targetWayPoint = _startWayPoint.NextWayPoint;
        } else {
            _targetWayPoint = _startWayPoint;
        }
        StartCoroutine (MyAI());
    }
    //第一种在Update里,使用主进程来写
    /*
    void Update(){
        //巡逻前提->不用追击英雄
        Debug.Log("update...");
        //判断是否到达追击的范围
        if (Vector3.Distance (transform.position, _playerPoint.transform.position) < 5) {
            Debug.Log ("发现玩家...");
            if (Vector3.Distance (transform.position, _playerPoint.transform.position) < 1) {
                //播放攻击动画
                Debug.Log ("攻击动画...");
            } else {
                //追击
                Debug.Log ("追击中...");
                _targetPoint = _playerPoint;
                transform.LookAt (_targetPoint.transform);
                transform.Translate (Vector3.forward * Time.deltaTime*2f, Space.Self);
            }

        } else {
            //巡逻
            Debug.Log ("巡逻中...");
            Vector3 v = _targetWayPoint.transform.position;
            if (Vector3.Distance (transform.position, v) < 0.5f) {
                _targetWayPoint  = _targetWayPoint.NextWayPoint;
                Debug.Log("巡逻下一个点"+_targetWayPoint.name);
            }
            transform.LookAt (_targetWayPoint.transform.position);
            transform.Translate (Vector3.forward * Time.deltaTime*2f, Space.Self);
        }
    }
*/
    //以下使用协程来写
    //巡逻
    IEnumerator MyAI(){
        while (true) {
            Vector3 v = _playerPoint.transform.position;
            if (Vector3.Distance (transform.position, v) > 5f) {
                Debug.Log ("巡逻中...");

                Vector3 nextP = _targetWayPoint.transform.position;
                if (Vector3.Distance (transform.position, nextP) < 0.5f) {
                    Debug.Log ("走下一个巡逻点");
                    _targetWayPoint = _targetWayPoint.NextWayPoint;
                    yield return new WaitForSeconds (1);
                } 

                transform.LookAt (_targetWayPoint.transform);
                transform.Translate (Vector3.forward * Time.deltaTime, Space.Self);

            } else {
                //Debug.Log ("发现玩家");
                yield return StartCoroutine (MyNewAI ());

            }
            yield return new WaitForEndOfFrame ();
        }
    }
    //追击
    IEnumerator MyNewAI(){
        while (true) {
            Vector3 PPos = _playerPoint.transform.position;
            if (Vector3.Distance (transform.position, PPos) > 5) {
                Debug.Log ("玩家超出追击范围,继续巡逻...");
                yield break;
            } else {
                if (Vector3.Distance (transform.position, PPos) < 1) {
                    Debug.Log ("攻击中...");
                } else {
                    Debug.Log ("追击玩家...");
                    _targetPoint = _playerPoint;
                    transform.LookAt (_targetPoint.transform.position);
                    transform.Translate (Vector3.forward * Time.deltaTime, Space.Self);
                }
            }
            yield return new WaitForEndOfFrame ();
        }
    }
}

总结

  1. 这个WayPoint路点寻路AI,其实一开始就一直在检查、获取玩家距离,
  2. 如果玩家玩家距离过大,就进行巡逻逻辑
  3. 当玩家进入设置的距离范围时,则调用追击、攻击的逻辑

猜你喜欢

转载自blog.csdn.net/liaoshengg/article/details/81018673