行为树(BT)[Millington 09]是现代游戏开发中最受欢迎的工具之一。 行为树是对简单决策树方法的扩展,类似于大型的“ if-then-else”代码语句。 这使得BT似乎是一种相对简单明了的技术,正是这种感知到的简单性以及它们最初的易用性,从而导致BT在大多数主要游戏引擎中得到广泛采用并得以实施[Epic 18,Johansen 18]。 因此,关于该技术的介绍,实施和优化,有很多信息,但是关于最佳实践和使用的适用性却很少。
由于缺乏此类信息,加上“银弹”思维,导致在所有经验水平上的广泛滥用。 这种滥用导致整体树的大小和复杂性使得几乎没有功能退化的风险就几乎不可能进行扩展或重构。 将感知到的简单性与缺乏有关内在问题的信息以及缺乏有关如何最好地利用该技术的信息相结合,结果是无论是对于新手还是有经验的开发人员而言,这些都是刻板的定时炸弹。 本章旨在讨论该技术的弱点以及常见的滥用方式。 最后,我们将讨论用于代理致动的适应性行为树。
在深入讨论BT之前,我们需要简要介绍一些AI基础知识。 在标准的AI代理模型(图1)中,我们具有三个不同的层/阶段:感测,决策和促动(作用).
感觉层负责将游戏世界的当前状态反映/重新解释为AI可以理解的格式。 然后,决策层负责决定代理在给定游戏世界的当前状态下需要采取哪些动作(如果有)。 最后,致动层负责执行所决定的动作过程。
让我们以需要喝杯咖啡的示例来说明各个阶段。 感觉可能检测到我们感到有点疲倦,也许我们也有点冷。 然后,决策层将处理该信息,并得出结论,我们应该获取一种含咖啡因的温暖品种的饮料,并且咖啡会是完美的。 然后,执行动作将执行一系列动作,首先进行然后喝下那杯咖啡,信息图层之间的AI代理模型流应该是单向的,并且任何层都不应干扰其上的任何层.
现在,传统上将BT视为决策层的一部分,不幸的是,在我们已经看到的大多数实现中(包括作者自己过去的实现[Anguelov 14]),BT中的节点通常负责这两个方面。 决策以及执行。 例如,在FPS游戏中,BT可能具有确定我们是否应该处于掩护状态的节点,然后选择掩护,然后执行移动和射击命令作为叶子任务。 在一个系统中将两个不同层的职责混合在一起,违反了“关注点分离”的软件工程原理[Greer 08],并且通常具有一定的体系结构味道。 我们将在第3节和第4节中详细讨论为什么这是一个问题,但是目前重要的是,我们首先对决策主题进行简单说明:决策本质上是周期性的
我们的意思是,代理将在其生命周期内不断在各种决策之间进行切换。 这些决策通常会根据一组确定性规则重复进行。
如果我们考虑上面使用的FPS游戏示例,我们可以想象在最高级别上的战斗循环看起来类似于图2a所示。 特工将在一组战斗行为之间不断切换。 图2b显示了争斗游戏中老板打架的游戏循环,这里的AI具有固定的动作/行为模式,需要在战斗期间进行动作和循环。 再次强调的重点是,无论是游戏还是问题:决策本质上都是周期性的。
行为树:它们如何工作
如前所述,BT是决策树的扩展,因为从其根开始评估一棵静态树,以根据当前的环境状态决定课程。 每次需要做出决策时,决策树总是从根开始进行评估,并且树本身传统上不是有状态的。 对树的重新评估使我们能够切换代理行为,而不管我们当前处于什么状态,只要满足相关分支条件即可。
BT采纳了这个概念,并通过添加显式树状状态和长期运行的任务对其进行扩展。 这意味着,当我们在后续更新中重新评估树时,可能会最终到达包含先前评估的状态的同一叶节点。 这使我们现在可以在树中拥有顺序流构造(即序列/并行节点),这在无状态决策树中是不可能的.
随着BT的普及和树中内容的爆炸式增长,每次AI更新时从树的根部重新评估该树在计算上都变得昂贵,因此导致了事件驱动的BT的发展[Epic 18,Champandard 12]。 尽管这极大地提高了性能,但由于对环境事件的反应性也产生了问题,因为我们不再评估以前发生故障的分支,并且直到当前选择的分支完成或发生故障,行为切换才会发生。 这极大地复杂化了BT的概念以及一般的树创作,需要开发其他技术和工具,例如 监视/服务节点[Epic 18,Anguelov 14],以恢复丢失的功能。
对各种BT范式及其发展历史的深入讨论超出了本章的范围。 有兴趣的读者可以参考以下资源以获取更多信息[Millington 08,Champandard 08,Champandard 12]。 在本章的其余部分讨论BT时,我们将参考事件驱动的BT模型,因为它是BT实现中最受欢迎的事实标准。
树流和可视化
BT的主要吸引力之一是它们易于可视化,因此可视化/编写/调试BT的工具非常普遍。 由于起源于决策树,大多数工具会将BT可视化为基于深度优先遍历顺序的简单的自上而下,从左到右的树。
这种可视化清晰地向用户传达了两组信息:树的深度和操作顺序。 这种可视化使节点从左到右的顺序过载,从而传达了决策的优先级和操作顺序。 就BT的功能而言,树的深度是无关紧要的信息,但是我们经常将整个轴专用于此。 给定树的最重要的可视数据点是:决策的优先级和操作顺序。 因此,我们建议使用一种可视化方法,其中从上到下的顺序代表决策的优先级,从左到右的顺序代表动作的顺序。 我们还强烈建议从可视化中省略诸如顺序和并行节点之类的标准流量控制节点,因为它们只会增加混乱,对用户几乎没有价值。 可以使用不同的颜色,容器和线条样式来可视化节点连接,从而实现各种控制流节点之间的视觉区别。
为说明起见,图4以下面两种格式显示了相同BT的表示。 重要的是要注意,有很多生活质量可视化无法在图中显示,例如 突出显示给定序列的所有节点,等等。本章的其余部分将针对所有BT示例使用此可视化方案
反应性
为了讨论反应性(即高级行为转换)主题,我们将使用FPS游戏的行为树示例(如图4a所示)。 假设在对树的第一次评估中,座席将进入“空闲”状态。 由于树评估将在下一次评估时从空闲分支恢复,因此我们只能通过以下两种方式之一触发完全重新评估:当前活动行为完成(或失败),或者我们明确重置树。
因此,我们需要某种机制来在发生环境变化时需要通知树,该环境变化需要重新设置树(行为转换)。 这通常是通过注册监视/服务节点来实现的,该监视/服务节点将连续轮询树执行之外的环境,并在满足其重置条件后触发树重置(即行为更改)。 图4b显示了处于空闲状态时已注册的监视节点(深灰色)。 还需要注意的是,树越深,我们注册的监视器越多,因此每次更新的树的评估成本也就越高。 当这些注册的监视器之一触发时,我们将重置整个树状态并从根节点重新评估树,这将选择适合于当前环境状态的新行为。