上次提到了一些行为树的基本概念,包括行为节点,控制节点(选择,序列,并行),这次来更多,更深入的讨论行为树的一些东西,如果对行为树不是很了解,请参看这里

一. 关于选择节点的讨论

我们说过选择节点的定义是通过判断子节点的前提条件来选择一个节点执行,这就牵涉到判断顺序的问题,是自左向右,还是随机选择,或者其他的一些规则等等,这样就延伸出各种各样的选择节点。

  • 带优先级的选择节点(Priority Selector): 这种选择节点每次都是自左向右依次选择,当发现找到一个可执行的子节点后就停止搜索后续子节点。这样的选择方式,就存在一个优先级的问题,也就是说最左边 的节点优先级最高,因为它是被最先判断的。对于这种选择节点来说,它的子节点的前提设定,必须是“从窄到宽”的方式,否则后续节点都会发生“饿死”的情 况,也就是说永远不会被执行到,为了更清楚的说明,看下面第一张图,这三个子节点在一个带优先级的选择节点下,它们的 前提会被依次判断,可以看到这个三个子节点的前提从左向右,一个比一个更严格,如果我们现在a为9,按照下图的定义会执行第一个子节点,如果a为7,则会 执行第二个子节点,如果a=11,则会执行第三个子节点。下面的第二张图演示了一种节点“饿死”(Starvation)的情况,我们看到第一个子节点的 前提,比第二个子节点更宽泛,只要a<10,那自左向右判断的话,永远会进第一个节点,所以,如果要用到带优先级的选择节点,则必须检查每一个子节点的前提,以防止节点饿死的情况.

  • 不带优先级的选择节点(Non-priority Selector):这种选择节点的选择顺序是从上一个执 行过的子节点开始选择,如果前提满足,则继续执行此节点,如果条件不满足,则从此节点开始,依次判断每一个子节点的前提,当找到一个满足条件的子节点后, 则执行该节点。这种方式,是基于一种称之为“持续性”的假设,因为在游戏中,一个行为一般不会在一帧里结束,而是会持续一段时间,所以有时为了优化的目 的,我们可以优先判断上一个执行的节点,当其条件不满足时,再寻找下一个可执行的节点。这种寻找方式不存在哪个节点优先判断的问题,所以对于前提的设置的 要求,就是要保证“互斥”(Exclusion)。如果我们用上面第一张图来说明,如果我们把控制节点换成不带优先级的选择节点,可以看到,当a=3时,第二个子节点会被执行,下一次当a变成9时,由于不是从头依次判断前提的,所以,我们还是会选择第二个节点,而不是我们可能期望的第一个节点。正确的做法见下图,注意每一个子节点的前提是“互斥的”。所以对于不带优先级的选择节点,它子节点的排列顺序就不是那么重要了,可以任意排列。

  • 带权值的选择节点(Weighted Selector):对于这种选择节点,我们会预先为每一个分支标注一个“权值”(Weight Value),然后当我们选择的时候,采用随机选择的方式来选,随机时会参考权值,并且保证已经被测试过的节点的不会再被测试,直到有一个节点的前提被满足,或者测试完所有的节点。带权值的选择节点对于子节点前提由于随机的存在,所以子节点的前提可以任意,而不会发生“饿死”的情况,一般来说,我们通常会把所以子节点的前提设为相同,以更好的表现出权值带来的概率上的效果。当所有子节点的权值一样时,这种选择节点就成为了随机选择节点(Random Selector)带权值的选择节点对于需要丰富AI行为的地方,非常适用,比如养成类游戏中,小狗表示开心的时候,可能会有各种各样的表现,我们就可以用这种选择节点,添加各种子节点行为来实现。

这些就是常用的选择节点类型,我们可以根据需要,定义更多的选择节点的选择行为,其实我们可以看到,不同的选择行为对于子节点前提的要求会有略微的不同,这是在我们搭建行为树的时候需要注意的地方。

二. 关于并行节点结束条件的讨论

我们每个节点都会有一个运行状态,来表示当前行为是否结束。对于控制节点来说,它的运行状态就是其子节点的运行状态,选择节点和序列节点比较好处 理,因为对于这两种控制节点来说,每时刻,只会有一个子节点在运行,只要返回在运行的这个子节点的状态即可。但对于并行节点来说,它同时刻会有多个子节点 运行,那我们如何来处理并行节点的运行状态问题呢?一般有两种:

  • 与:只有所有的子节点都运行结束,才返回结束。
  • 或:只要有一个子节点运行结束,就返回结束。

为什么要需要有节点的运行状态呢?

  • 序列控制节点中,需要用运行状态来控制序列的执行
  • 外部世界需要了解行为的运行状态,来决定是否要更新决策(如果行为树在决策层)/请求(如果行为树在行为层),关于AI分层,请参考这里

对于第二点,可以举个例子,比如我们有一个行为是“走到A点”,假设这个行为是不可被打断的,那当我们在走向A点的过程中,行为树的运行状态就是 “正在执行”,当到达A点时,行为树就返回“已完成”,这样,对外部来说,当我们看到行为树是“正在执行”的时候,我们就不需要做任何新的行为(为了优 化,或者为了行为抖动等等),当看到“已完成”的时候,我们就可以做新的决策或者行为了。这样一个运行状态还有助于我们检测行为树的状态,帮助调试。

三.关于具体实现的讨论

行为树的实现可以有多种多样,我这边提出一些建议,一般来说,行为树每个节点需要有进入(Enter),离开(Exit),运行(Execute) 等部分,需要有行为节点(ActionNode),控制节点(ControlNode),前提(Precondition)等基类,然后,还需要定义行为 树的输入(InputParam)和输出(OutputParam),一般来说,我们希望行为树是一个黑盒,也就是说,它仅依赖于预定义的输入。输入可以 是黑板(Blackboard),工作池(Working Memory)等等数据结构,输出可以是请求(Request),或者其他自定义的数据结构,如下图:

代码的话,就不写了,因为blog没有代码插件,写代码效果不是很好,以后我会在TsiU里面发布一个行为树的库的版本。

四.关于绘制和调试的讨论

看到行为树的定义后,作为程序员的直觉,我们很自然的就会想到,这好像应该能做一个工具来辅助行为树的创建和调试,我们可以把预定义好的前提和节 点,在一个可视化的编辑器里搭建成行为树,然后再导出成数据给游戏用。对于调试来说,我们可以让工具和游戏通信,然后实时的检测行为树的运行状况,比如当 前在哪个分支中等等。由于行为树的逻辑是可见的,并且是静态的,所以我们看其选择的路径,我们就可以知道AI为什么会作出这样的决策了。当我刚接触到行为 树的时候,就在想做这样一个编辑器,但迫于项目压力,一直没有时间做(工作量还是挺大的),有兴趣,有时间的朋友,可以考虑做一个。顺便说一句,我现在对 于行为树的搭建都是在代码中完成的,虽然没有数据驱动那么“先进”,但通过宏定义,排版等方式,还是能非常清晰的表示树的整体结构。

关于行为树,我想这个系列就到这里了。在使用行为树的过程中,可能还会碰到这样和那样的问题,包括我自己在实践中的一些经验,我想就先不包括在这个系列里了,以后再单独拿出来聊,这个系列作为行为树的入门,希望对大家有所帮助,欢迎指教和讨论。

————————————————————————
作者:Finney
Blog:AI分享站(http://www.aisharing.com/)
Email:finneytang@gmail.com
本文欢迎转载和引用,请保留本说明并注明出处
————————————————————————

9

 

[转]BEHAVOUR TREE2的更多相关文章

  1. Extjs tree2

    本案例中记载了Extjs中一棵树的形成以及各种案例集成,并详解介绍了TreePanel.TreeNode和AsyncTreeNode这三个主要对象.纯属个人业余时间玩玩的,整理出来,方便以后查看. J ...

  2. [转]BEHAVOUR TREE

    自从开博以来,每天都会关心一下博客的访问情况,看到一些朋友的订阅或者访问,不胜欣喜,也促使我去写一些更好的博文,来和大家分享和交流,从访问 统计来看,有相当一部分是来自于搜索引擎的流量,关键字以“行为 ...

  3. 脑洞大开加偏执人格——可持久化treap版的Link Cut Tree2

    试了一下先上再下的Treap方式,很高兴,代码变短了,但是,跑的变慢了!!!其实慢得不多,5%左右.而且这个版本的写法不容易写错..只要会一般可持久化Treap的人写着都不难...就是相对于(压行的) ...

  4. Graph & Tree2

    续https://www.cnblogs.com/tyqtyq/p/9769817.html 0x65 负环 SPFA 当一个节点入队次数到达N的时候,就说明有负环 或者记录最短路包含的路径条数 还有 ...

  5. pcl曲面网格模型的三种显示方式

    pcl网格模型有三种可选的显示模式,分别是面片模式(surface)显示,线框图模式(wireframe)显示,点模式(point)显示.默认为面片模式进行显示.设置函数分别为: void pcl:: ...

  6. jQuery.zTree的跳坑记录

    最近项目用到树型结构的交互,一开始并不打算选择zTree,为了项目进度我妥协了,这一妥协后果就是我进坑了,在2天的挣扎中,我终于跳出坑了,活了下来,有一些感慨纪录下来. 有一个业务场景需要2个树型结构 ...

  7. Python使用总结二

    近来因为工作需要,用Python比较多,写得多了,收获也多.借此记录总结一下,方便以后反思. 一.IDE的选择 1.notepad++加上cmd窗口 前些时候写python脚本都用notepad++编 ...

  8. 剑指Offer面试题:17.树的子结构

    一.题目:树的子结构 题目:输入两棵二叉树A和B,判断B是不是A的子结构.例如下图中的两棵二叉树,由于A中有一部分子树的结构和B是一样的,因此B是A的子结构. 该二叉树的节点定义如下,这里使用C#语言 ...

  9. 强大的自适应jQuery焦点图特效

    jQuery焦点图切换自适应效果 自适应jQuery焦点图特效是一款支持移动端的响应式jQuery焦点图插件,支持flexible布局,支持移动触摸事件等. 今天我们要来分享一款很灵活的jQuery焦 ...

随机推荐

  1. ajax的data传参的两种方式

    ajax的data传参的两种方式 本文为转载. 1.[javascript] view plain copy /** * 订单取消 * @return {Boolean} 处理是否成功 */ func ...

  2. 阮一峰:RSA算法原理(一)

    今天看到一篇好文章,关于加密算法,收藏了觉得不过瘾,还是自己贴一遍,也能加深一下印象. 原文链接:http://www.ruanyifeng.com/blog/2013/06/rsa_algorith ...

  3. 【转】理解cookie和session机制

    cookie和session机制之间的区别与联系 具体来说cookie机制采用的是在客户端保持状态的方案.它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持.cookie的作用就 ...

  4. PHP中的include、include_once、require、require_once

    include.include_once().require.require_once() 作用: 通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件( ...

  5. HDU 4906 Our happy ending(2014 Multi-University Training Contest 4)

    题意:构造出n个数 这n个数取值范围0-L,这n个数中存在取一些数之和等于k,则这样称为一种方法.给定n,k,L,求方案数. 思路:装压 每位 第1为表示这种方案能不能构成1(1表示能0表示不能)   ...

  6. 企业需要k2来解放孤岛危机

    当我谈孤岛危机时,我谈些什么?你以为我要说的是一款风靡的游戏?那恐怕要让你失望了,今天要谈的是“企业管理体系孤岛”,但更多人甚至都没意识到这是危机. 下面的场景,也许你会觉得似曾相识. 场景一 某制鞋 ...

  7. PL/SQL : Procedural Language / Structual Query Language and it is an exrension to SQL.

    SQL is not very flexible and it cannot be made to react differently to differing sutuations easily. ...

  8. Andoid activity 生命周期

    今天介绍一下Android中最常用的组件activity的生命周期.当activity处于Android应用中运行时,它的活动状态由Android以Activity栈的形式管理.当前活动的Activi ...

  9. Map-Reduce的工作机制

    Mapper “Map-Reduce”的思想就是“分而治之” Mapper负责“分”,即把复杂的任务分解为若干个“简单的任务”而执行 “简单的任务”有几个意思:1.数据或计算规模相对于原任务要大大缩小 ...

  10. Windows Server 2012 R2 设置

    一.任务栏左下角启动服务器管理器,然后进行设置.1.登录不显示服务器管理器 2.本地服务器,看到右边的IE增强的安全配置,如图所示,关闭两项内容.这样就关闭了IE增强安全提示框. 3.“工具”菜单,启 ...