游戏AI(Game AI),是指在游戏中,由已经写定好的程序控制的“类人化玩家”,俗称电脑玩家。一般的游戏AI能够拥有对真实玩家的一系列操作感知的能力并对此作出交互行为,比如:攻击(Attack),逃跑(Run away)等。而且AI所做出的反应并不是凭空生成,而是通过模仿真实玩家的操作使其行为富有“智能化(Intelligent)”。
需要注意的是,一般的游戏AI与我们讨论计算机视觉、自然语言处理等领域时所说的AI(人工智能)并不相同,考虑到游戏的开发成本,周期以及家用计算机处理能力,游戏AI的智能度相对较低。不过随着硬件的发展,游戏AI始终会朝着真正AI的方向发展。
游戏AI中通常分为定性和非定性两种。
目前游戏AI基本归结为三个部分的能力:感知,思考,动作。
朴素AI指的是仅仅使用简单的分支语句(if…else或switch…case)对AI的行为进行判别和分类。
举个栗子,一个敌方士兵在基地站岗,拥有以下几个基本行为:
IF…ELSE实现:
if(AI.HP == 0){ AI.Dead(); }else if(AI.HP > 0 && AI.HP <= 0.2){ AI.FindBunker(); }else if(AI.Distance - Player.Distance <= 2){ AI.Attack(); }else if(AI.Distance - Player.Distance <= 5){ AI.MoveToPlayer() }else{ AI.Patrol(); }
由于游戏中有多种AI,每种AI的行为方式不尽相同,用这种方法我们需要为每一种AI单独写一份代码,几乎没有可重用性,会使开发人员的工作量增大。但是因为朴素AI的效率高,代码直观,所以一般用在项目初期的测试以及应急时期。
有限状态机是一种抽象机制,通常设定了各种不同的预定状态。有限状态机也可以定义一连串的条件,以便确认何时应该改变状态,当一个事件的发生,将会触发一个动作,或者执行一次状态的迁移。FSM中一定存在两种状态–初始状态和结束状态,在启动一个FSM时,首先必须将FSM置于“起始状态”,然后通过输入一系列操作,最终,FSM会到达“结束状态”或者“消亡状态”。
任何一个FSM都可以用状态转换图来描述。这里我仍然拿上一个栗子来说,下面是一个实际栗子的状态转换图:
简单的FSM代码:
private Enemy enemy = new Enemy(); public void EnemyAction() { if(enemy.HP){ status = AI.Dead(); }else if(enemy.HPLower){ status = AI.FindBunker(); }else if(enemy.CloseToPlayer){ status = AI.Attack(); }else if(!enemy.CloseToPlayer && enemy.DistanceToPlayer){ status = AI.MoveToPlayer() }else{ status = AI.Patrol(); } }
FSM相比于朴素AI的优点:
但是也有缺点:
Behavior Tree是一种树状的数据结构。每次调用都会从根节点开始遍历,自顶向下,通过一些条件来检索这颗树,最终确定需要做的行为并执行。下面是一个简单的行为树:
在游戏中,行为树的父节点统称控制节点,而子节点则称行为节点。
事实上,行为树又称决策树,因为整棵树最主要的部分是控制节点,它需要对条件进行决策,判断出需要执行的正确的行为。
行为树的优点不仅在于它逻辑清晰,而且我们可以对其控制节点自定义判断。一般简单的自定义控制节点有三种:
不过单独使用行为树也是有缺点:
无论是什么游戏,游戏AI所使用的最好的方法从来不是一个,而是通过不同类型AI来寻找适合该时期使用的方法:状态机+行为树,朴素AI+状态机+行为树等等。随着游戏的不断发展,游戏AI也还有很大的成长空间,会有更多的算法和优化方法去构造更加智能的游戏AI。