安徽省住房城乡建设厅网站,自助建站工具,轻量级网站开发,手机单页面网站模板Unity自学之旅05 Unity学习之旅⑤#x1f4dd; AI基础与敌人行为#x1f94a; AI导航理论知识#xff08;基础#xff09;开始实践 #x1f383; 敌人游戏机制追踪玩家攻击玩家子弹碰撞完善游戏失败条件 #x1f917; 总结归纳 Unity学习之旅⑤
#x1f4dd; AI基础与敌… Unity自学之旅05 Unity学习之旅⑤ AI基础与敌人行为 AI导航理论知识基础开始实践 敌人游戏机制追踪玩家攻击玩家子弹碰撞完善游戏失败条件 总结归纳 Unity学习之旅⑤ AI基础与敌人行为 AI导航
理论知识基础
一、导航系统的基本组件
NavMesh导航网格 NavMesh 是 Unity 中 AI 导航的基础它是一个表示可行走区域的网格。它将场景中的可行走表面如地面、楼梯等进行三角剖分形成一个平面的网格用于代理Agent导航。生成 NavMesh 的步骤 首先需要将场景中的几何体标记为静态Static以便 Unity 可以将它们纳入 NavMesh 的计算。然后打开 Navigation 窗口Window - AI - Navigation在 Bake 选项卡中调整设置例如 Agent Radius代理半径、Agent Height代理高度等这些设置决定了代理在场景中占用的空间大小和形状。点击 Bake 按钮Unity 会生成 NavMesh显示为场景中的蓝色网格。 NavMeshAgent导航网格代理 这是附加在游戏对象上的组件用于让对象在 NavMesh 上移动。主要属性 Speed代理的移动速度。Acceleration代理的加速度。Stopping Distance距离目标多远时停止移动。Radius代理的半径用于避障和计算可行走区域。Height代理的高度决定了代理可以通过的最小空间高度。 NavMeshObstacle导航网格障碍物 该组件用于表示场景中的动态障碍物。当一个对象附加了 NavMeshObstacle 时它会影响 NavMeshAgent 的导航路径。可以设置为 Carve 模式这会在 NavMesh 上动态地修改 NavMesh使代理能够绕开障碍物。
二、导航行为和逻辑
路径规划 NavMeshAgent 会自动根据 NavMesh 为代理规划从当前位置到目标位置的最短路径。它会考虑障碍物和可行走区域。可以使用 agent.remainingDistance 来检查代理离目标的剩余距离使用 agent.pathStatus 来查看路径的状态如是否完成、正在计算或被阻塞。 避障 Unity 的导航系统会自动处理代理之间和代理与障碍物之间的避障。通过设置 NavMeshAgent 的属性如 Radius 和 Avoidance Priority可以调整避障行为。代理之间会根据彼此的 Avoidance Priority 进行避障较低优先级的代理会主动避让较高优先级的代理。 动态导航 当场景中的障碍物或目标位置发生变化时NavMeshAgent 会自动重新计算路径。例如如果要在游戏运行时改变目标位置可以调用 agent.SetDestination(newDestination); 其中 newDestination 是一个 Vector3 类型的新位置。
开始实践
window→package manager 选择 Unity Registry 然后搜索 AI Navigation window→ai→navigation(obsolete) 这里是因为我所使用的Unity版本那个AI Navigation static 已经弃用了我更改了一种使用方式。 选择Environment然后为点击Inspector中的Static,接着将Environment的对象及其子对象都设置为Navigation Static. 点击Bake→bake 为Enemy添加NavMeshAgent让敌人可以在NavMesh上面行走。 绘制几个路径点用于敌人的自动巡逻。 引用巡逻点,编辑EnemyBehavior脚本 // 巡逻点的transformpublic Transform PatrolRoute;// 四个巡逻点的transform集合public ListTransform Locations;void Start(){// 脚本运行时初始化巡逻路径InitializePatrolRoute();}void InitializePatrolRoute(){foreach (Transform t in PatrolRoute){Locations.Add(t);}}让Enemy跟着巡逻点动起来在此编辑脚本
// ...
// 默认第一个索引为0即先走第一个巡逻点
private int _locationIndex 0;// NavMeshAgent的引用
private NavMeshAgent _agent;void Start()
{// 获取Enemy对象上的NavMeshAgent组件的引用_agent GetComponentNavMeshAgent(); // 脚本运行时初始化巡逻路径InitializePatrolRoute(); MoveToNextPatrolLocation();
}// 移动到下一个巡逻点
void MoveToNextPatrolLocation()
{_agent.destination Locations[_locationIndex].position;
}
//....现在只会移动到第一个巡逻点然后我们的目的是在每个巡逻点循环往复的进行移动这个时候就需要在Update()中搞点事情了。
void Update()
{// 检测当前对象与目标位置距离if(_agent.remainingDistance 0.2f !_agent.pathPending){MoveToNextPatrolLocation();}
}// 移动到下一个巡逻点void MoveToNextPatrolLocation(){if(Locations.Count 0) return;_agent.destination Locations[_locationIndex].position;// 索引循环往复_locationIndex (_locationIndex 1) % Locations.Count; }敌人游戏机制
敌人按照巡逻路线进行巡逻当与玩家碰撞后减少玩家生命值然后敌人回到初始位置玩家也可以攻击敌人减少其生命值。
追踪玩家
当玩家进入敌人警戒范围时敌人会直接奔向玩家。 // 玩家的Transform引用public Transform Player;void Start(){// ...// 获取Player对象的引用Player GameObject.Find(Player).transform;}// ...// 碰撞触发器void OnTriggerEnter(Collider other){if(other.name Player){// 玩家进入到警戒范围后敌人奔向玩家_agent.destination Player.position;Debug.Log(玩家进入警戒范围);} }攻击玩家
攻击玩家的逻辑很简单当玩家与敌人发生碰撞时玩家减少生命值并且在GUI上显示
修改玩家的Playerbehavior脚本敌人脚本也可以因为碰撞是相互的
// gameManager的引用因为HP,收集道具数量都在该处存放
private GameBehavior _gameManager;void Start(){// 将当前player的刚体组件获取并设置_rb GetComponentRigidbody();// 获取当前角色的胶囊碰撞体_col GetComponentCapsuleCollider();_gameManager GameObject.Find(Game_Manager).GetComponentGameBehavior();}// 发生碰撞时void OnCollisionEnter(Collision collision){// 如果与敌人碰撞则HP-1if (collision.gameObject.name Enemy){_gameManager.HP - 1;}}这里的话需要注意一个问题就是敌人身上的碰撞体为碰撞触发器勾选了Is Trigger,然后直接通过Player的OnCollisionEnter()并不会触发需要给敌人再加入一个碰撞体就可以了。 子弹碰撞
为Player添加反击手段逻辑就是敌人有三滴血当子弹射击三次并且击中敌人后敌人自动销毁。
编辑敌人Enemy的游戏脚本
// 敌人的HP3
private int _lives 3;
public int EnemyLives
{get { return _lives; }set{_lives value;if (_lives 0){Destroy(this.gameObject);Debug.Log(敌人死亡);}}
}void OnCollisionEnter(Collision collision)
{// 当子弹碰撞到敌人时if(collision.gameObject.name Bullet(Clone)){EnemyLives - 1;Debug.Log(遭受子弹射击);}
}完善游戏失败条件
逻辑是生命值为0时游戏暂停出现一个按钮说你输了。
先绘制一个Button按钮和之前的一样默认禁用即可当生命值为0时在脚本内调用。 编辑GameManager的脚本
public Button LossButton;
private int _playerHp 10;
public int HP
{get { return _playerHp; }set{//...if (_playerHp 0){ProgressText.text You want another life with that?;LossButton.gameObject.SetActive(true);Time.timeScale 0f;}else{ProgressText.text Ouch... thats got hurt.;}Debug.LogFormat(HP{0}, _playerHp);}
}总结归纳
本文主要介绍了在 Unity 中实现 AI 导航以及构建敌人游戏机制的方法。包括导航系统的基本组件、导航行为和逻辑以及敌人的巡逻、追踪玩家、攻击玩家、被子弹击中和完善游戏失败条件等功能。
重要亮点
导航系统基本组件Unity 中 AI 导航的基础是 NavMesh它将场景中的可行走表面进行三角剖分形成网格。NavMeshAgent 是附加在游戏对象上用于在 NavMesh 上移动的组件NavMeshObstacle 用于表示动态障碍物。导航行为和逻辑NavMeshAgent 能自动规划从当前位置到目标位置的最短路径处理避障和动态导航。例如当场景中的障碍物或目标位置变化时会自动重新计算路径。敌人巡逻机制通过为敌人添加 NavMeshAgent设置巡逻点编写脚本实现敌人在巡逻点之间循环往复移动。追踪玩家当玩家进入敌人警戒范围时敌人会奔向玩家。通过在敌人脚本中检测玩家进入碰撞触发器设置敌人的目标位置为玩家位置。攻击玩家当玩家与敌人发生碰撞时玩家减少生命值。在玩家脚本和敌人脚本中分别处理碰撞事件。完善游戏失败条件当玩家生命值为 0 时游戏暂停出现 “你输了” 按钮。在游戏管理器脚本中根据玩家生命值控制按钮的显示和游戏时间的暂停。