游戏AI - 行为树Part1:简介
背景
在游戏领域,大多数AI是按照既定规则运行的,并未采用过于复杂的技术,主要有以下两方面原因: 一方面,从风险成本考虑,引入新技术意味着程序员要开发相应的算法和框架,游戏设计师需重新学习设计方法并摸索算法的适用范围。对于小团队而言,这样的开销难以承受;而大团队则担心新技术运用不当会损害自身声誉。 另一方面,“高级”的AI算法不够直观,设计难度较大。以利用神经网络训练士兵AI为例,有一种做法是设计师通过几个按键操作士兵进行移动和攻击,程序自动记录敌我双方的数据以及设计师的操作,最后利用这些信息作为输入构建行为树。但这种方法存在三个问题:一是效率极低,因为若数据量不足,行为树可能无法覆盖所有情况,然而“足够”的数据量并无明确标准;二是错误的操作也会被记录下来,虽然可以开发功能删除设计师的某个动作,但这增加了额外的工作量;三是行为树的结果如同黑箱,难以解释。
由于上述原因,一般公司更倾向于使用传统的有限状态机。有限状态机虽名称拗口,但其概念较为简单,它包含有限个状态以及状态间的转换条件,本质上类似于多个if...else...语句。下面通过一个英雄的故事来进一步理解:
从前有一个胆小的英雄,他的行为规则如下:
- 看到哥布林,就会跑过去攻击;
- 看到半兽人,就会逃跑;
- 既看不到哥布林也看不到半兽人,就会休息;
- 同时看到哥布林和半兽人,也会逃跑。
从这些行为中可以抽象出一个有限状态机。有限状态机符合我们的认知习惯,但它存在一个致命缺点:随着状态和转换条件的增加,其复杂度会急剧上升,修改难度极大。例如,每增加一个状态,就需要增加若干条转换线,状态越多,需要增加的转换线也就越多。
正因如此,越来越多的开发者开始采用行为树。
行为树
定义
行为树的概念比状态机更为复杂。行为树是一种包含逻辑节点和行为节点的树结构。当需要确定一个行为时,会从树的根节点开始,遍历各个节点,找出第一个与当前数据相匹配的行为。下面结合之前的英雄故事,以行为树的形式进行更生动的解释:
这个行为树与之前的有限状态机等价。其中,Root是根节点,每次寻找行为时都必须从这里开始。Priority Selector是一个逻辑节点,它会从左到右遍历其子节点,若子节点的准入条件与当前信息相符,则执行该子节点。例如,若英雄只看到哥布林,“Orc in sight”这个准入条件不满足,“Escape”行为不会执行;“Globlin in sight”条件满足,因此执行“Fight”行为。由于“Fight”在“Idle”的左边,其优先级更高,所以“Idle”不会执行。在这个例子中,“Idle”可视为默认行为。
优点
通过简单对比行为树和有限状态机,可以发现行为树具有以下优点:
- 易于拓展:行为树引入了逻辑节点,减少了转换条件(即连线更少、更清晰),使得拓展AI变得更加容易。
- 行为重用:行为树支持行为的重用。例如,“Escape”和“Fight”都包含跑的行为,“Fight”还包含砍怪的行为。
Sequence也是一个逻辑节点,它会从左到右按顺序执行子节点,并且只有在前一个子节点执行完成后才会执行下一个子节点。在这个例子中,“Do Run”需要有一个判断是否到达目的地的方法,当该方法返回结束信号时,才会执行“Do Slash”。“Escape”和“Fight”中的“Do Run”行为节点是相同的,因此“Do Run”是一个可重用的节点。在行为树中,我们可以编写好“Do Run”“Do Slash”等基础行为节点,并设定一些准入条件,从而组合出千变万化的AI。 - 并行执行:
Parallel是一个逻辑节点,它允许所有子节点同时运行。其结束条件可以根据需求设定,既可以是所有子节点都完成时结束,也可以是任一子节点完成时结束。
总结
- 节点类型:行为树包含三种节点,分别是根节点
Root、可拓展的逻辑节点(如Priority Selector、Sequence、Parallel)以及行为节点。 - 优势特点:在复杂情况下,行为树比有限状态机更加清晰、易于拓展,有利于逻辑的重用。设计良好的行为树能够实现多样化的AI行为。
后续,我将展示在游戏开发中如何将行为树作为框架进行应用。
作者:伍一峰 来源:知乎