前言
一个简单的人工智能WayPoint
WayPoint: 游戏中敌人根据几个巡逻点自动巡逻,在巡逻过程中,时刻监听英雄(敌人)和自己距离是否达到追击范围(不巡逻,追击英雄),在追击过程中,监听是否达到攻击范围(不追击,攻击)。
所需对象
- 当前玩家
- 敌人
- 3个巡逻点
每个对象的脚本
脚本类
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 ();
}
}
}
总结
- 这个WayPoint路点寻路AI,其实一开始就一直在检查、获取玩家距离,
- 如果玩家玩家距离过大,就进行巡逻逻辑
- 当玩家进入设置的距离范围时,则调用追击、攻击的逻辑