利用之前的介绍建立这样一个简单的场景,蓝色方块是静态的,灰色方块带有Nav Mesh Obstacle组件,这两种方式都可以形成障碍物。红色圆柱是敌人,白色的则是玩家,我们要为敌人制作巡逻功能。
我们建立了四个空物体,way(1-4)调整他们的位置,任何位置都可以,但由于我们的地板垂直于y方向,所以way的y值没有实际意义,而超出地板的x和z值最终会导航到地板边缘。
之后为了获取方便,把它们挂到另一个空物体EnemyWay下,这样我们只需获取到这个父物体的Transform组件,利用GetChild()方法就可以像访问数组一样,访问每一个子物体。
代码如下,将它挂到Enemy上:
using System.Security.Principal;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyPatrol : MonoBehaviour
{
public float patrolSpeed = 3f; //巡逻速度
public float patrolWaitTime = 0.5f; //巡逻等待时间
public Transform patrolWalPoints; //巡逻路线
private NavMeshAgent agent; //导航组件
private float patrolTimer = 0f; //计时器
private int wayPointIndex = 0; //巡逻路线目录
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
Partrolling();
}
public void Partrolling()
{
agent.isStopped = false;
agent.speed = patrolSpeed;
//Debug.Log(agent.remainingDistance);
//remainingDistance是距离目标点的距离长度,stoppingDistance表示距离目标点stoppingDistance长度时开始停止
if(agent.remainingDistance <= agent.stoppingDistance)
{
//此时敌人停止,计时器开始计时
patrolTimer += Time.deltaTime;
//等待完毕,敌人可以继续行动,找到下一个目标点,重置计时器
if(patrolTimer > patrolWaitTime)
{
if(wayPointIndex == patrolWalPoints.childCount - 1)
{
wayPointIndex = 0;
}
else
{
wayPointIndex++;
}
patrolTimer = 0;
}
}
//设置目的地
agent.destination = patrolWalPoints.GetChild(wayPointIndex).position;
}
}
注:值得注意的是,敌人不会马上停在stoppingDistance的这个距离,由于加速度是有限制的,导航网格代理 (NavMesh Agent)组件上有一个变量Acceleration表示最大加速度,增大它的值会让物体更快停下,所以stoppingDistance不是停止距离,而是开始停止的距离。