现在机器人没有行走动画,那么我们先把它的Position和rotation关闭了,仅保留它的导航功能
void Awake()
{
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
agent.destination = wayPoints[index].position;
agent.updatePosition = false;
agent.updateRotation = false;
}
当然,循环那里也要添加
index++;
index %= 4;
agent.destination = wayPoints[index].position;
agent.updatePosition = false;
agent.updateRotation = false;
patrolTimer = 0;
给机器人添加EnemyAnimation脚本,
注:(打开机器人的状态机发现angularspeed正的,向右旋转,负的向左旋转,因此如果导航的方向在机器人的面向的右侧,应该向右旋转,导航方向在机器人左侧,向左旋转,怎么判断导航方向在机器人面向的左侧还是右侧呢?
可以通过左手定则,把机器人面向设为a,导航方向设为b(不能弄反),得到a,b的叉乘向量,如果result为正,说明b在a左侧,反之右侧。在代码中用vector3 v=Vector.Cross(a,b);来模拟
状态机的speed怎么弄呢,导航的期望速度的方向在机器人面向方向的投影,真正的速度就是投影的长度(也即投影.magnitude),代码中调用vector.project();注意的是测试的时候发现速度过大,要调整机器人属性navMeshAgent中speed的大小
private UnityEngine.AI.NavMeshAgent agent;
private Animator anim;
void Awake()
{
anim = GetComponent<Animator>();
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}
void Start () {
}
void Update () {
//如果导航的期望速度是0,也即到达目标,就把机器人状态机的速度和角速度全部置零
if (agent.desiredVelocity==Vector3.zero)
{
anim.SetFloat("speed",0);
anim.SetFloat("angularspeed", 0);
}
else//否则如果没有到达目标
{
float angle = Vector3.Angle(transform.forward, agent.desiredVelocity);
float angleHudu = 0;
if (angle > 90)
{
anim.SetFloat("speed", 0);//大于90度速度为0,只转向
}
else
{
Vector3 projection = Vector3.Project(agent.desiredVelocity, transform.forward);
anim.SetFloat("speed", projection.magnitude);
}
angleHudu = angle * Mathf.Deg2Rad;//角度转成弧度
Vector3 crossResult = Vector3.Cross(transform.forward, agent.desiredVelocity);
if (crossResult.y<0) //得到的叉乘小于0,
{
angleHudu = -angleHudu;
}
anim.SetFloat("angularspeed", angleHudu);
}
}
做完了巡逻,接下来该做机器人追捕代码(只粘贴追捕代码)
void Awake()
{
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
agent.destination = wayPoints[index].position;
agent.updatePosition = false;
agent.updateRotation = false;
sight = GetComponent<EnemySight>();
void Update () {
if (sight.playerInsight) //如果主角在视野内,进行射击动作
{
}
else if(sight.alertPosition!=Vector3.zero) //进行追捕
{
Chasing();
}
else //否则巡逻状态
{
Patrolling();
}
}
//机器人追捕函数
private void Chasing()
{
agent.speed = 6;
agent.updatePosition = false;
agent.updateRotation = false;
agent.destination = sight.alertPosition;
if (agent.remainingDistance<2f)
{
chaseTime += Time.deltaTime;
if (chaseTime>chaseTimer)
{
sight.alertPosition = Vector3.zero;
GameController._instance.lastPlayerPosition = Vector3.zero;
GameController._instance.alermOn = false;
}
}
}
补充:把cctv摄像头的collision的gameboject物体的mesh collider的is trigger勾选,它是检测人物,不是障碍物