游戏开发中AI
文章的思路来源于Voidmatrix大神视频总结,以及一些本人开发BossAI的感悟所写。
附上大神原视频链接:【游戏开发秘籍】状态机?行为树?一个视频速通游戏开发中的AI!#06
游戏AI是什么
**游戏开发领域中,AI通常指的是对非玩家角色行为的设计与研究,让他们能够感知周围的环境,并且做出相应的动作表现。**例如和玩家交互聊天的NPC、按照特定规则巡逻的怪物或是直接与玩家进行对抗的人机等等,一个能与我们的游戏玩法相匹配,逻辑自洽的角色,除去策划上的工作,在开发技术上也是大有研究的。
游戏AI的核心目标
- 增强体验:通过智能的NPC行为、动态难度调整等提升游戏趣味性。
- 创造挑战:让敌人或对手具备合理的策略,避免过于简单或作弊。
- 模拟世界:构建逼真的生态系统(如《荒野之息》中的动物行为)。
状态机(FSM)
最经典最简单的AI实现技术便是状态机,我们可以把NPC的每一个具体的行动都拆分成一个独立的状态。
接下来我们只需要设计好状态间的挑战条件就可以了,譬如 NPC拥有巡逻、攻击、逃跑和治疗4个状态,默认的入口状态为巡逻,也就是在这个NPC在程序中被实例化添加到游戏世界中时,它便会巡视自己的领地。按照固定的路线徘徊,当玩家等敌对角色进入到他的视野范围后,状态机便会跳转到攻击的状态,在攻击状态下,他会持续逼近玩家的位置,并且试图对其造成伤害。而当在这个战斗过程中自身生命值低于一定数值时,NPC就会进入到逃跑状态,在逃离玩家一定范围后,他们也会停下来治疗自己,恢复生命值,然后继续进入到巡逻或是战斗的状态循环,整套逻辑,这样一个栩栩如生的NPC角色就诞生在了我们创造的游戏世界中了。
而作为最经典的压实线状态机的实验代码,可以说是最简单的了。
以前面空洞武士项目教程中的代码为例,对于状态节点的设计,我们除去执行更新到 update接口外,通常还需要预留on inter和on X的接口,用来通知该状态的进入并进行初始化以及处理状态退出式的逻辑,譬如在攻击状态进入和退出时,我们需要设置NPC手持武器道具的可见性,并且更新其锁敌感知范围的逻辑,对于状态机本身等待提供 update的更新方法外,也还需要提供设置入口状态,切换状态和注册新状态的接口,为了更快捷的查找,在实际开发过程中,我们可以使用媒体书读或是哈希表来存储状态ID到具体状态对象的映射,那么在状态机更新的过程中,实际执行了当前选中的状态攻击方法,在设置入口状态或是切换不同的状态时,也只需要根据传入的ID,将当前状态指针指向不同的具体状态对象即可。
状态机的弊端
不过跟过空洞武士项目介绍的同学其实可能就已经意识到了这台机正如AI实现方法的弊端了,**不同的状态之间彼此穿插,如果我们要新增一个状态或是修改已有的状态跳转条件时,都需要考虑与现有状态的调整关系,当系统的状态数过多时,维护各个状态间的关系就会变得非常困难。**那么封装的思想这时就起作用了,我们能否把功能相似的具体状态封装成一个更大的抽象状态,我们只需要去关注不同抽象状态间的跳转,思路便会清晰很多。
分层状态机
以前面的NPC行动为例,我们现在需要在巡逻攻击淘宝和治疗4个游状态中加入新的工作状态角色在巡逻一段时间没有发现威胁后,会进入到工作状态,收集环境、中的、资源来制作武器和药品等道具。这工作状态显然又分为收集和制作2个子状态,如果我们依然按照先前的思路,那么这6个状态间的跳转关系就开始变得有些让人眼花缭乱了。
我们做以下改进:
- 巡逻和攻击状态归类为战斗状态
- 逃跑和治疗归类为恢复状态
- 收集和制作归类为工作状态
这样原本错综复杂的状态关系现在变非常清晰了,我们只需要维护好父级状态间的跳转条件,并且在父状态内部理清子状态的条件,一切就又可以水到渠成,井然有序了,而这便是分层状态机的实现。
尽管如此,分层状态机也并没有从根本上避免前面所说的缺点,尤其是我们采用代码描述AI逻辑时每一次修改都需要对状态机内部的代码进行侵入式的改动,维护成本依然很高,所以进入状态机的游戏AI仅适用于一些逻辑简单,行为固定的游戏角色。
AI行为树(Behavior Tree)
行为树是一种形式化的图形建模语言。使用明确定义的符号系统来描述大规模软件工程上的需求。
在游戏中,AI行为树一般由以下几类节点构成。
- 根节点(Root):根节点是行为树的入口,与前面提到的状态机初始状态相似,根据点的返回值为其子节点的执行结果。
- 组合节点:组合节点构成了行为树的骨架,用于控制行为树的执行顺序,完成类似程序语言中的跳转语句的功能。组合节点下又可以分为三类,分别是顺序节点、选择节点和随机节点。
- 顺序结点:依次遍历子节点直到某个子节点返回失败。
- 选择节点:依次执行直到返回成功。
- 随机节点:按照设置好的概率,随机直接选择某个子节点执行
- 装饰节点:装饰节点用于修改其子节点执行结果。可以用于将子节点的返回结果进行逻辑取反,或是限制执行次数的。
- 叶子节点:实现具体的AI行为逻辑
- 条件节点:用于判断具体情景
- 动作节点:驱动实现AI的动作
行为树在游戏更新的过程中,从根节点出发,从左到右依次遍历每个子节点及其子数,根据每个节点的规则计算并返回其执行结果。
在实际的游戏开发过程中,通常使用引擎等可视化工具下网制作流程图一样,对行为树进行编辑和设计,在发布和运行时这种行为描述逻辑会被渲染为代码或者支持动态解析的数据。相较于状态机,行为树的灵活性大大提升了,我们从根结点出发,按照规则便可以轻松找到一条描述最终选择的决策路径,再添加新的业务逻辑时,也不会因为与其他逻辑产生耦合,从而导致修改困难,但行为树的这种建模思想更为抽象一些,以及支持行为树运行的run time,代码也会更为复杂。此外相较于状态机在更新时只需要调用当前状态的更新逻辑行为,树更新时通常需要从根节点出发,经过漫长的路径选择执行流,才能找到合适的行动。
所以从纯粹的性能角度讲,行为树的运行时代价会比状态机略高,而在工程实践中,我们通常会对行为书的选择进行缓存或者适当降低决策频率。提到决策频率,这个话题还是大有研究的,在游戏更新的过程中,我们其实无需在每一个游戏帧中都执行AI的行为决策树,高频的决策take,在短时间内得到相同的动作结果,在游戏行为上是毫无意义的。
就像现实生活中的人一样,当我们有了新的决策去执行新的动作时,就算是此时有了突发情况打断了我们的持续行为,我们也会需要一定的思考时间来重新规划我们的行动策略以及频率过高的AI决策不仅会浪费程序性能,在很多时候也会让AI对玩家的行为过于敏感,从而产生敌不动我不动的毒指令错觉所以在游戏开发的过程中,我们通常会刻意让AI在决策之间发呆,故意延迟一段时间再执行新的决策,那么这个时间长度又如何设置?对于绝大多数的行为保证行动策略take间隔为0.5~1秒之间,就可以足够通用。
但对于特殊的需求我们也要灵活调整,以前面讲述的巡逻索敌战斗决策循环为例,敌人AI有巡逻状态到锁敌状态的间隔时间可以尽可能短小,因为所击范围对于玩家来说并不可见,更快的感知可以让AI看起来足够机敏,而对于玩家脱离感知范围后,敌人恢复到巡逻的状态,中的,角色切换这个间隔可以适当放长,从而模拟出丢失玩家视野后,敌人继续向着目标点追踪一段距离的效果,更符合现实情况,而不会出现玩家一离开区域,敌人便恢复到若无其事的机械感。
效用系统(Utility AI)
基于目标标效应的AI也是一种在游戏开发中较为常见的设计,我们注意到游戏AI的核心是行为选择,无论是状态机还是行为树,都是将逻辑使用图形化的模型或者语言来进行抽象,但由于状态节点和行为数据节点关注的往往是与游戏环境直接相关的局部信息,而当我们需要综合游戏全局信息进行决策时,便需要考虑很多,这就容易导致行为树的复杂度爆炸。
类比现实,我们仍在执行某个行动时,通常是为了具体的某个目的从而切换了行动,就像吃饭是因为饿了需要填饱肚子,睡觉是因为困了,需要恢复精力,就算是无所事事在大街上闲逛,那也是因为我们需要找到填充我们无聊时间的乐子,类比到游戏中的AI我们也可以构建一种需求-效应模型来告知AI可预期的奖励,让AI根据自己的目标自行规划行动路线,这种AI在《模拟人生》这类游戏中被广泛使用,以及在《王者荣耀》等moba类游戏中,人机对局时,AI也会根据效用评估选择打野对线或是战斗支援等不同的策略来来进行执行。
原理:通过评分系统选择最优行为(如“攻击=0.7,躲藏=0.3”)。
机器学习(ML)
在游戏开发中,机器学习(ML)正逐渐改变传统AI的设计方式,使其具备更强的适应性和动态学习能力。监督学习可用于模仿玩家行为,例如《Forza Horizon》中的“Drivatar”系统,通过分析真实玩家的驾驶数据来训练AI对手,使其驾驶风格更接近人类。强化学习(RL)则让AI通过试错来优化策略,如《星际争霸2》的AlphaStar和《Dota 2》的OpenAI Five,它们通过数百万次模拟对战学习高级战术,甚至击败职业选手。然而,RL的训练成本极高,且可能产生过于强大但缺乏趣味性的AI,因此开发者常结合模仿学习(Imitation Learning)来加速训练过程,如《GT赛车7》的“Sophy AI”在模仿人类驾驶后,再通过RL微调提升表现。
生成式AI
生成式AI的兴起为游戏带来了更丰富的动态内容。例如,GPT类模型可用于NPC对话生成,如《AI Dungeon》利用GPT-2创造开放式剧情,而《天际》的Mod“AI Voice Dialogue”结合语音识别和大语言模型,让NPC的对话更加自然。在美术和关卡设计方面,生成对抗网络(GAN)和变分自编码器(VAE)可辅助生成独特的地形或角色模型,如《No Man’s Sky》使用神经网络优化其程序化生成系统,确保宇宙探索的多样性。
总结
游戏AI作为游戏开发的核心技术之一,其设计理念和方法论经历了从简单到复杂、从静态到动态的演进过程。本文系统梳理了游戏AI的主要实现方式及其适用场景,为开发者提供了清晰的技术选型思路。
技术演进路径:
- **状态机(FSM)**作为最基础的方法,适合简单行为逻辑,但存在状态爆炸和维护困难的问题。分层状态机通过抽象层级缓解了这一矛盾,但仍无法从根本上解决耦合性问题。
- **行为树(BT)**采用模块化设计,通过组合节点、装饰节点和叶子节点的架构实现了更好的扩展性,特别适合复杂决策场景。虽然运行时开销略高,但通过决策频率优化可以取得良好平衡。
- **效用系统(Utility AI)**引入目标导向思维,通过效用评分实现更自然的决策过程,在模拟类游戏中表现优异。
- **机器学习(ML)**代表了前沿方向,监督学习、强化学习等技术正在重塑AI开发范式,但需要权衡训练成本与游戏性需求。
实践建议:
- 中小型项目可优先考虑行为树+效用系统的混合架构
- 对性能敏感的场景建议采用分层状态机优化
- 创新性项目可尝试机器学习方案,但需建立完善的评估机制
- 决策频率控制在0.5-1秒区间能平衡响应性与自然感
未来展望:
随着生成式AI技术的发展,动态叙事、个性化内容生成等新范式正在兴起。多智能体系统、边缘计算等方向也将拓展游戏AI的可能性边界。但需要始终牢记:优秀的游戏AI应该服务于玩法体验,在"智能"与"趣味"之间找到最佳平衡点。