unity技术日志之十九秘密潜入:敌人AI设定(完结篇)
现在我们来给敌人添加“EnemyAI”脚本,这个脚本等同于敌人的大脑,根据它脚本传递的信息,决定敌人的行为。 新建”EnemyAI“脚本拖入到”char_robotGuard“中。 ”char_robotGuard“脚本代码: using UnityEngine; using System.Collections; public class EnemyAI : MonoBehaviour { //敌人将有三个状态:巡逻、追踪、射击 //敌人射击时是静止的,但是要设定敌人的巡逻和追踪速度,分别为2和5 public float patrolSpeed=2f; public float chaseSpeed=5f; //当敌人到达最后发现玩家的位置或是巡逻的路径点时 //敌人会短暂停留等待一会儿,所以要设置巡逻和追踪的等待时间 public float chaseWaitTime=5f; public float patrolWaitTime=1f; //存储敌人的路径点坐标 public Transform[] patrolWayPoints; private EnemySight enemySight; // EnemySight脚本引用 private NavMeshAgent nav; // nav mesh agent组件引用 private Transform player; // 玩家位置引用 private PlayerHealth playerHealth; // PlayerHealth脚本引用 private PlayerLastSighting lastPlayerSighting; // LastPlayerSighting脚本引用 private float chaseTimer; // 追踪等待时间的计时器 private float patrolTimer; // 巡逻等待时间的计时器 private int wayPointIndex; // 路径点数组的索引 void Awake () { // 获取引用对象和组件 enemySight = GetComponent<EnemySight>(); nav = GetComponent<NavMeshAgent>(); player = GameObject.FindGameObjectWithTag(Tags.player).transform; playerHealth = player.GetComponent<PlayerHealth>(); lastPlayerSighting = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<PlayerLastSighting>(); } void Update(){ //判断进入每个状态的条件,然后调用相应的函数 //如果玩家在敌人视线范围内,并且HP大于0 if (enemySight.playerInSight && playerHealth.health > 0f) { Shooting (); } else if (enemySight.personalLastSighting != lastPlayerSighting.resetPosition && playerHealth.health > 0f) {//如果最后发现玩家的位置不是玩家重置位置,并且HP大于0 Chasing (); } else { Patrolling(); } } //射击状态 void Shooting(){ //射击时不让敌人移动 //后续的射击功能将由“EnemyShooting”脚本控制 nav.Stop (); } //追踪状态 void Chasing(){ //把追踪位置设为最后发现玩家的位置 //但只有在敌人当前位置与最后发现玩家位置的距离大于一定数值时才会这儿做 //获取敌人当前位置与最后发现玩家位置的向量 Vector3 sightingDeltaPos = enemySight.personalLastSighting - transform.position; //上面的“一定数值”设为2,所以检测向量长度的平方是否大于4 if (sightingDeltaPos.sqrMagnitude > 4f) { //追踪位置等于最后发现玩家的位置 nav.destination=enemySight.personalLastSighting; } //我们确保敌人是跑向追踪位置的,所以让敌人等于追踪速度 nav.speed=chaseSpeed; //判断玩家是否到达了追踪位置 //检测敌人与追踪位置的剩余距离,是否小于可停止距离 if (nav.remainingDistance < nav.stoppingDistance) { //敌人原地等待,追踪等待时间的计时器开始计时 chaseTimer += Time.deltaTime; //检测计时器时间是否大于敌人需等待的时间,如果条件满足,敌人将返回各自的巡逻路径中 // 当敌人等待了足够时间后(设定的5秒) if (chaseTimer >= chaseWaitTime) { // 重置最后发现玩家的全局位置和独立位置 重置计时器 lastPlayerSighting.position = lastPlayerSighting.resetPosition; enemySight.personalLastSighting = lastPlayerSighting.resetPosition; chaseTimer = 0f; } } else { // 如果敌人没有靠近玩家最后出现的位置 那么重置计时器(因为追踪位置不是固定的 玩家可能还会在其他位置触发警报 从而刷新追踪位置) chaseTimer = 0f; } } //巡逻状态 void Patrolling(){ //让敌人移动速度等于巡逻速度 nav.speed = patrolSpeed; //判断路径点的索引是否需要增加 //检测玩家敌人是否已经接近目标路径点或者没有目的地 // 如果没有目标点 或者 已接近目标巡逻点 if (nav.destination == lastPlayerSighting.resetPosition || nav.remainingDistance < nav.stoppingDistance) { //巡逻计时器计时 patrolTimer += Time.deltaTime; //检测是否计时器大于等于巡逻等待时间 if (patrolTimer >= patrolWaitTime) { //索引移至下一个,从而设置新的目标路径点 if (wayPointIndex == patrolWayPoints.Length - 1) { wayPointIndex = 0; } else { wayPointIndex++; } patrolTimer = 0f; } } else { // 如果没有靠近任何一个目标点 重置计时器 patrolTimer = 0; } //设定目的地为路径点位置 nav.destination = patrolWayPoints [wayPointIndex].position; } } 把”char_robotGuard“保存到”Prefabs“,下面我们把敌人实例放置到场景的其他地方。 复制”char_robotGuard“,Position(-19,0,37),再复制一个Position(-29,0,43.5),为了区分它们,重命名。选中场景最下方的敌人,给名称添加编号“_001”,以此类推。 最后一步,给敌人设置巡逻路径点,我们把所有路径点都放到一个父对象中,创建一个空的“GameObject”命名为“wayPoints”,重置坐标,这样路径点的局部坐标也等于全局坐标。复制一个wayPoints”,重命名为“wayPoints_001”,然后把它拖入到”wayPoints”中成为子对象。由于路径点是空的“GameObject”,如果你不单独选中的话是无法在场景中看到的。这个问题可以使用“2D Gizmos”解决,“2D Gizmos”是一个图标,用来表示对象在场景视图中的位置,选中“wayPoints_001”点击按钮,选择“Other”,然后搜索“wayPoint”找到相应图标

复制十个“wayPoint_001”并重新进行编号。

1-4号点是第一个敌人的巡逻路径点,“wayPoint_001”Position(-26.75,0,7),“wayPoint_002”Position(-25.4,0,14.5),“wayPoint_003”Position(-18.8,0,14),“wayPoint_004”Position(-18.5,0,7)。 5-8号路径点的坐标: “wayPoint_005”Position(-10,0,36.4),“wayPoint_006”Position(-10,0,44.8),“wayPoint_007”Position(-17.9,0,44.8),“wayPoint_008”Position(-17.8,0,36.4)。 9-11号路径点的坐标: “wayPoint_009”Position(-27,0,35.4),“wayPoint_010”Position(-17.9,0,43),“wayPoint_011”Position(-28.2,0,43)。 最后给敌人添加相应的路径点,选中“char_robotGuard_001”,找到“EnemyAI”脚本组件,把1-4号路径点,按顺序拖入“Patrol Way Points”中。

以此类推,“char_robotGuard_002”5-8路径点。 “char_robotGuard_003”跟其他不一样,与2共用8这个路径点,9-8-10-11路径点。

要确保添加路径点的顺序是正确的 选中“char_ethan”,把“Audio-》endgame“拖入到”Death Clip“。

W:向前,S:向后,A:向左,D:向右,X:喊叫 shit+W/S/A/D:潜伏 这是开启电梯的钥匙。

到达电梯门开启电梯便胜利
