上次提到了一些行为树的基本概念,包括行为节点,控制节点(选择,序列,并行),此次来更多,更深刻的讨论行为树的一些东西,若是对行为树不是很了解,请参看这里。 程序员
一. 关于选择节点的讨论 数据结构
咱们说过选择节点的定义是经过判断子节点的前提条件来选择一个节点执行,这就牵涉到判断顺序的问题,是自左向右,仍是随机选择,或者其余的一些规则等等,这样就延伸出各类各样的选择节点。 dom
这些就是经常使用的选择节点类型,咱们能够根据须要,定义更多的选择节点的选择行为,其实咱们能够看到,不一样的选择行为对于子节点前提的要求会有略微的不一样,这是在咱们搭建行为树的时候须要注意的地方。 编辑器
二. 关于并行节点结束条件的讨论 工具
咱们每一个节点都会有一个运行状态,来表示当前行为是否结束。对于控制节点来讲,它的运行状态就是其子节点的运行状态,选择节点和序列节点比较好处理,由于对于这两种控制节点来讲,每时刻,只会有一个子节点在运行,只要返回在运行的这个子节点的状态便可。但对于并行节点来讲,它同时刻会有多个子节点运行,那咱们如何来处理并行节点的运行状态问题呢?通常有两种: 测试
为何要须要有节点的运行状态呢? 优化
对于第二点,能够举个例子,好比咱们有一个行为是“走到A点”,假设这个行为是不可被打断的,那当咱们在走向A点的过程当中,行为树的运行状态就是“正在执行”,当到达A点时,行为树就返回“已完成”,这样,对外部来讲,当咱们看到行为树是“正在执行”的时候,咱们就不须要作任何新的行为(为了优化,或者为了行为抖动等等),当看到“已完成”的时候,咱们就能够作新的决策或者行为了。这样一个运行状态还有助于咱们检测行为树的状态,帮助调试。 google
三.关于具体实现的讨论 spa
行为树的实现能够有多种多样,我这边提出一些建议,通常来讲,行为树每一个节点须要有进入(Enter),离开(Exit),运行(Execute)等部分,须要有行为节点(ActionNode),控制节点(ControlNode),前提(Precondition)等基类,而后,还须要定义行为树的输入(InputParam)和输出(OutputParam),通常来讲,咱们但愿行为树是一个黑盒,也就是说,它仅依赖于预约义的输入。输入能够是黑板(Blackboard),工做池(Working Memory)等等数据结构,输出能够是请求(Request),或者其余自定义的数据结构,以下图: 插件
代码的话,就不写了,由于blog没有代码插件,写代码效果不是很好,之后我会在TsiU里面发布一个行为树的库的版本。
四.关于绘制和调试的讨论
看到行为树的定义后,做为程序员的直觉,咱们很天然的就会想到,这好像应该能作一个工具来辅助行为树的建立和调试,咱们能够把预约义好的前提和节点,在一个可视化的编辑器里搭建成行为树,而后再导出成数据给游戏用。对于调试来讲,咱们可让工具和游戏通讯,而后实时的检测行为树的运行情况,好比当前在哪一个分支中等等。因为行为树的逻辑是可见的,而且是静态的,因此咱们看其选择的路径,咱们就能够知道AI为何会做出这样的决策了。当我刚接触到行为树的时候,就在想作这样一个编辑器,但迫于项目压力,一直没有时间作(工做量仍是挺大的),有兴趣,有时间的朋友,能够考虑作一个。顺便说一句,我如今对于行为树的搭建都是在代码中完成的,虽然没有数据驱动那么“先进”,但经过宏定义,排版等方式,仍是能很是清晰的表示树的总体结构。
关于行为树,我想这个系列就到这里了。在使用行为树的过程当中,可能还会碰到这样和那样的问题,包括我本身在实践中的一些经验,我想就先不包括在这个系列里了,之后再单独拿出来聊,这个系列做为行为树的入门,但愿对你们有所帮助,欢迎指教和讨论。