在上一节的基础上进行完善Enemy类。 首先添加这些变量。
public float chaseSpeed = 6f;//追踪速度 public float chaseWaitTime = 5f;//追踪时间 private float chaseTimer = 0f;//已经追踪的时间 public float sqrPlayerDist = 4f;//与玩家的距离 private bool chase = false;//是否追踪 public float shootRotSpeed = 4f;//视角的旋转角度 public float shootFreeTime = 2f;//射击的冷冻时间 private float shootTimer = 1.5f;//已经射击的时间 private EnemySight ememySight;//敌人的视野 private Transform player; public Rigidbody buttle;然后在start中初始化一些变量
ememySight = transform.Find("EnemySight").GetComponent<EnemySight>(); player = GameObject.FindGameObjectWithTag("Player").transform;射击方法和追踪方法都是每帧执行的,所以需要写在update中, 在update中完善代码
if (ememySight.playerInSight == true)//如果玩家在敌人的视野内 { Shooting(); chase = true; } else if (chase)//如果处于追踪状态 { Chasing(); } else { Patrolling();//巡逻状态 }在下面新建方法Shooting 射击的过程是首先需要敌人的方向朝向玩家的方向,然后进行射击。
void Shooting() { Vector3 lookPos = player.position;//敌人朝向的位置 lookPos.y = transform.position.y;//因为玩家和敌人有可能y值不一样,所以这里将高度进行统一,防止抬头低头 Vector3 targetDir = lookPos - transform.position; //敌人的朝向转向目标的方向 transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetDir), Mathf.Min(1f,Time.deltaTime * shootRotSpeed)); agent.isStopped = true;//让敌人处于停止状态 if (Vector3.Angle(transform.forward, targetDir) < 6)//如果现在的方向是玩家的方向,这里有个容错范围 { if (shootTimer > shootFreeTime) { //实例化出子弹 Instantiate(buttle, transform.position, Quaternion.LookRotation(player.position - transform.position)); shootTimer = 0f; } shootTimer += Time.deltaTime; } }添加Chasing方法 追踪的过程是首先根据最后发现玩家的位置进行追踪,如果还是没有找到的话就等待一段时间然后恢复巡逻状态。
void Chasing() { agent.isStopped = false; Vector3 sightDeltPos = ememySight.playerLastSight - transform.position;//根据最后一次玩家出现的位置进行追踪 if (sightDeltPos.sqrMagnitude > sqrPlayerDist) { agent.destination = ememySight.playerLastSight; } agent.speed = chaseSpeed; if (agent.remainingDistance < agent.stoppingDistance)//敌人已经走到玩家最后出现的位置了 { chaseTimer += Time.deltaTime; if (chaseTimer > chaseWaitTime) { chase = false; chaseTimer = 0f; } } else chaseTimer = 0f; }