《Unity3D高级编程之进阶主程》第八章 AI(2)-用行为树构建AI

前面讲了用状态机来构建游戏中的怪物AI,由于它易于理解,容易被人类接受,扩展性和耦合性都很好,所以状态机的用途很广泛。但是状态机也有很大的缺点,就是不能处理和模仿太复杂的智能行为,比如模拟一个人类奔赴一场大型战役中,对战场中的各种繁多的突发事件做出符合人类模式的处理,这种方式状态机就无能为力,由于突发情况太多,组合起来的突发情况更多,做出反应的方式也变化多端,用人类思维逻辑去编写每个状态,状态的数量就会如指数级攀升无法应付,不止人类大脑无法应付这么复杂的逻辑编写,这样复杂的逻辑也很难有效维护。

===

行为树很好的弥补了状态机的缺点,它简化了逻辑拼凑的方式,让脑容量有限的人类能更容易编写和控制机器人的智能行为。这也是AI架构的关键点,能够让人更加简单容易的制作复杂的人工智能的行为,可以说是‘化繁为简’。

‘化繁为简’是我们的大部分编程时的重点,尤其在AI设计上,人工智能的行为方式大都是由人类头脑指定的行为方式,是人类头脑所预期的行为。制作出人类所预期的AI行为逻辑,并且制作的方式和过程又在人类大脑的承受范围内的是我们所预期的。状态机的方式制作AI理论上可以实现任何AI,但复杂到一定程度人脑无法承受,其实就是低效的或者说低阶的AI。行为树的优势就在这里,能够通过一些简单的操作制作出达到人类所预期的足够复杂的机器人行为方式。

行为树的本质是树状节点,每个节点可以选择某种类型的功能节点,也可以选择某个叶子节点即没有子节点功能,功能节点以各种逻辑顺序来选择继续访问下面的子节点或者直接停止并返回结果给父节点,子节点的结果将给父节点作为参考以便继续运行相关逻辑,因此行为树本身就是一种树形的父子节点之间的逻辑结构,我们可以理解为节点逻辑,通过扩展节点的功能来实现复杂的行为逻辑。

下面我们来详细介绍行为树的组成。

行为树(Behavior Tree)具有如下的特性,它有4大类型的节点:

1,Composite Node 复合节点

复合节点可详细的分为3种:

一种是Selector Node,即选择节点,它的节点规则是当执行本类型节点时,它将从头到尾迭代执行自己的子节点,如果遇到一个子节点执行后返回True则停止迭代,本节点向自己的上层父节点也返回True,否则所有子节点都返回False,那么本节点才向自己的父节点返回False。

另一种是Sequence Node,即顺序节点,它的节点规则是当执行本类型节点时,它将从头到尾依次迭代执行自己的子节点,如果其中一个子节点执行后返回False那么就立即停止迭代,同时本节点向自己的父节点也返回False,相反如果所有子节点都返回True,则本节点就向自己的父节点返回True。

还有一种是Parallel Node,即并发节点,它的节点规则是并发执行它的所有子节点。并发节点又分为三种策略,这与它们向父节点返回的值和并行节点所采取的具体策略有关即如下:

Parallel Selector Node,即并行选择节点,它的节点规则为执行完所有子节点,如果有一个子节点返回False则自己向父节点返回False,只有当所有子节点全返回True时自己才向父节点返回True。

Parallel Sequence Node,即并行顺序节点,它的节点规则为执行完所有子节点,如果有一个子节点返回True则自己向父节点返回True,否则只有当全部子节点返回False时自己才向父节点返回False。

Parallel Hybird Node,即并行混合节点,它的节点规则为执行完所有子节点,按指定数量的节点返回True或False后才决定返回结果。

并行节点提供了并发性,由于它可以在线程或协程级别提供并发操作,所以在性能上面有能够充分利用CPU提高性能。通常情况下,Parallel Node下会并行挂多个Action子树,或者挂多个条件节点以提供实时性。并行节点增加性能和方便性的同时,也增加了维护的复杂度。

除此以外为了进一步提高AI的复杂度和随机性,Selector 和 Sequence可以进一步提供非线性迭代的加权随机变种。比如,Weight Random Selector 即随机权重选择节点,每次执行不同的起点,提供了每次执行不同的First True Child Node的可能。而Weight Random Sequence 即随机权重顺序节点,则每次执行顺序不同,以提供了不同的随机迭代顺序,能使AI避免总出现可预期的结果让结果更加的随机化。

2,Decorator Node 修饰节点

Decorator Node,即修饰节点,修饰节点的功能为将它的子节点执行后返回的结果值做额外修饰处理后再返回给它的父节点。

这里举几个修饰节点的例子便于读书者们理解,下面这些修饰节点都可以自定义创造出来,节点功能可以为五花八门,它们共同点为修饰子节点的结果,或者通过子节点的结果来运行逻辑。

	反向修饰 Decorator Not,它的节点功能为将结果反置后返回上级处理,即当子节点为True时返回给自己父节点的则为False,反之子节点返回False时自己返回给父节点为True。

	直到失败修饰 Decorator FailureUntil,它的节点功能为子节点运行在指定的次数到达前一直向上级返回失败,指定次数后一直向上级返回成功。

	总是失败修饰 Decorator Fail,它的节点功能为无论子节点返回的结果是否为True都向上级返回False。

	计数修饰 Decorator Counter,它的节点功能为只运行子节点n次,运行计数超过n次后不再运行。

	时间修饰 Decorator Time,它的节点功能为在指定时间内运行子节点后都返回True,超出这个时间范围无论子节点返回什么结果都向上级返回False。		

	甚至Decorator Nothing 它的功能就是什么都不干,用来提前占个位置为后面的功能预留。

除了以上这些我们还可以创造出来更多种类型的节点,例如用来调试的日志(log)节点,告知开发者当前节点的位置及相关信息,或者循环修饰节点,循环执行子节点n次等等,我们可以根据项目的需求来增加必要的修饰节点逻辑。

3,Condition Node 条件节点

Condition Node相对比较简单,条件满足则返回Ture,否则返回False。

各式各样的条件节点,都继承基础条件节点并且返回Ture或False。比较常用的条件节点例如,大于,小于,等于,与,或,判断True或False。由这些条件节点可以与变量组合成,判断血量的条件,距离判断的条件,状态判断的条件,时间间隔判断条件等,可以用于行为树AI中。

4,Action Node 行为节点

Action Node,通常都是最后的叶子节点,它完成具体的一次(或一小步)行为并视需求返回值。行为节点可以是执行一次得到的结果,也可以视为分步执行很多次的行为。例如向前行走这个行为可以一直被执行直到走出某个范围。

我们可以通过扩展行为节点让AI行为变得更为丰富多彩,行为节点也是自主定义角色行为的关键,它通常涉及角色行为的具体行为。常用的行为节点的例如,行走到目标地点的行为节点,追击目标的行为节点,使用物品的行为节点,撤退的行为节点,攻击目标的行为节点,防御动作的行为节点,释放某技能的行为节点等等。这些行为节点都可以根据我们项目的需要从基础的行为节点扩展而来的,行为节点是最丰富的节点库,大部分时间我们程序员也一直在修改和扩容行为节点以向AI行为提供更多丰富的可编辑行为内容。

在行为树中任何节点被执行后,必须向其上层的父节点报告执行结果:成功True或失败False或Running正在运行(还在执行并未执行完毕,例如行走到某目的地,角色行走正在途中),这简单的成功或失败或运行中的汇报原则被很巧妙地用于控制整棵树的决策方向。

整棵行为树中,只有条件节点和行为节点才能成为叶子节点,也只有叶子节点才是需要特别定制的节点,而复合节点和修饰节点均用于控制行为树中的决策走向,所以有些资料中也统称条件节点和行为节点为Behavior Node 即表现节点,而复合节点和修饰节点为Decider Node 即决策节点。

行为树能够支撑起对复杂逻辑的AI的原因就是由于我们可以使用这些简单的节点去搭建一个庞大的AI行为树(也可以说是一个AI模型)。我们程序员很容易的扩展节点来丰富AI节点库,无论是复合节点、修饰节点、条件节点、还是行为节点在扩展时都是相对容易的且有良好的耦合性的,这使得我们在壮大AI行为时节点的功能性扩展变得很容易,而拼装这些节点形成一个完整的AI行为就如同是一个搭积木的过程,人脑能搭建多复杂的积木就能搭建起多复杂的行为树AI。

决策树也是与行为树相似的AI解决方案。决策树和行为树一样都是树形结构叶都是由节点构成。在决策树中决策的构成是由树形结构的头部开始,从上往下一路判断下去决策该往哪走,最后一定会执行到叶子节点,进而确定当次行为的动作。在决策树中只有叶子节点才决定了如何行动,而且在决定后的行动中无法中途退出,必须等到当次行为执行完毕或者被打断后才能开始下一次决策。从理念上讲,决策树就是为了制定决策,而行为树是为了控制行为,它们是两个不同的理念。行为树更加注重变化,而决策树则更加注重选择。因此行为树可以定制比决策树更加复杂的AI逻辑,而实现的难易程度上比较行为树并没有增加多少。

行为树比状态机更容易编写复杂的AI逻辑很大程度上是得益于单个节点的易扩展性,状态机的每个状态的扩展难度相对比较难。从人们拼装节点组合的角度看,AI树的可搭建更加丰富多彩的AI行为,而且它的搭建行为需要的能力也都是在人脑的可及范围内,而状态机对于稍微复杂点的AI行为搭建则非常费力,不仅需要更多的硬编码支撑而且状态间的连线也容易让人陷入困惑。

不过再厉害的人脑在搭建行为树AI时也有极限的搭建复杂度,无论你对搭建行为树这项技能有多么熟练多么精通都有到一个极限的状态。当搭建的复杂度超出人类大脑的时候我们就会陷入混乱,或者说无法完成更加复杂的AI行为。例如如果想完全模拟人类的思维判断逻辑,对不同的人,对不同的事,对不同的景色,对不同的物体,不同的路面,以及以上混合组合的不同组合作出应对策略,就完全超出了人类大脑搭建的极限。像这种特别复杂,完全不能由人类大脑通过搭建的方式形成的AI,我们就需要引入‘机器学习’技术,它不再由人来制定行为方式而是通过对案例的学习,从而获得更多更复杂的环境应对方式。

参考:

《使用行为树(Behavior Tree)实现游戏AI》by AKara 2010

· 书籍著作, Unity3D, 前端技术

感谢您的耐心阅读

Thanks for your reading

  • 版权申明

    本文为博主原创文章,未经允许不得转载:

    《Unity3D高级编程之进阶主程》第八章 AI(2)-用行为树构建AI

    Copyright attention

    Please don't reprint without authorize.

  • 微信公众号,文章同步推送,致力于分享一个资深程序员在北上广深拼搏中对世界的理解

    QQ交流群: 777859752 (高级程序书友会)