https://www.jianshu.com/p/29cc3307d7ae

参考
游戏AI - 行为树Part1:简介
游戏AI - 行为树Part2:框架
https://github.com/f15gdsy/BT-Framework
http://www.u77.com/game/3067

一、有限状态机

游戏中的AI,大多数都是按照规则设定好的,没有太多花哨的技术。原因有几个:

  • 一是出于风险成本的考虑,用一个新技术,需要程序员开发相应的算法和框架,游戏设计师重新上手设计方法和摸索算法的适用范围,小团队承受不起这样的开销,大团队又怕做坏名声;
  • 二是“高级”的AI算法并不直观,难以设计。举一个例子,怎么利用神经网络来训练一个士兵AI?我见过的一个例子是设计师用几个按键来操作士兵移动攻击,然后程序自动记录敌我双方的数据和设计师的操作,最后利用这些信息作为input构建一个行为树。这个方法的问题有三个,一是效率奇慢,因为如果数据不够,行为树就可能覆盖不了所有情况,但多少才是“够”,又没有定论;二是错误的操作也会被记录下来,当然可以开发一个功能来删除设计师的某个动作;三是行为树的结果是无法解释的,相当于一个黑箱。

由于上述的原因,一般的公司都会使用比较传统的有限状态机。

虽然第一次听的话可能会拗口,其实有限状态机的意思其实很简单,它包含了有限个的状态和状态间的转换条件。最直白的说法就是几个if...else...语句。为了弄明白这个概念,我们讲一个英雄的故事:

从前有一个胆小如鼠的英雄,

  • 他看到哥布林就会跑过去打它;
  • 他看到半兽人就会逃跑;
  • 他看不到哥布林也看不到半兽人就会休息;
  • 他看到哥布林也看到半兽人也会跑。

我们可以从中抽象出这样的一个有限状态机:

image.png

有限状态机很符合我们的认知,但它有一个致命的缺点——它随着状态和转换条件的增多而急速地变得错综复杂,以至于很难对它做出改动(想象一下,多加一个状态,则需要增加几条转换线,越多状态,需要增加的转换线越多)。也由于这个原因,比较多的开发者投入了行为树的怀抱。

二、行为树

行为树的概念会比状态机要复杂些——行为树是一个包含逻辑节点和行为节点的树结构,每次需要找出一个行为的时候,会从树的根节点出发,遍历各个节点,找出第一个和当前数据相符合的行为。很拗口对吧,下面来一个生动点的解释,继续上面的英雄的故事,但是是用行为树表达出来:

image.png

这个行为树是等价于之前的有限状态机的。其中Root是根节点,每次需要寻找行为的时候都必须从这里开始。

Priority Selector是一个逻辑节点,它的意思是从左到右遍历自己的子节点,如果子节点的准入条件符合信息的话,就执行该子节点。如果英雄只看到哥布林,那么Orc in sight这个准入条件不符合,Escape不执行;Globlin in sight符合,于是执行Fight;因为Fight在Idle的左边,所以Fight的优先程度更高,于是Idle不执行。在我们的例子中,Idle可以看作是default behavior。

1.优点

从简单的行为树和有限状态机的对比,我们就可以看出,行为树由于引入了逻辑节点,它的转换条件更加少(线更少,更清晰),让拓展AI变得更加容易。行为树还有另外一个优点:行为的重用(reuse)。例如,Escape有一个跑的行为,而Fight则有跑的行为,和砍怪的行为。请看图:

image.png

Sequence同样是一个逻辑节点,它的意思是从左到右按顺序执行子节点,并且仅仅在一个子节点执行完成后才执行下一个子节点。在例子中,Do Run需要有一个自己判断到达目的地的方法,当该方法返回end的时候,才会执行Do Slash。

Escape和Fight的Do Run行为节点是一样的,只是Fight多了一个Do Slash行为节点而已。所以Do Run是一个可以重用的节点。在行为树中,我们能够编写好Do Run,Do Slash这些基础的行为节点,和设定一些准入条件,就可以组成千变万化的AI了!

我们希望英雄在逃跑的时候群众发出嘘声,而在攻击的时候出现欢呼声:

image.png

省略了其他部分,只画Escape部分。Parallel是一个逻辑节点,它的意思是让所有子节点同时运行,那它什么时候结束呢,可以使当所有子节点都完成的时候结束,也可以让任一子节点完成时结束,视乎需要来做出选择。那么在攻击当中会是怎么样实现的呢?大家可以尝试画出来,习惯一下行为树的思维方式。

三、行为树关键词

在展开之前,我们先定义几个关键词(基本都以BT作为前缀...是Behavior Tree之意,别误会了...),会在下面的框架用到。

BTNode:所有节点的base class。定义了一些节点的基本功能,并提供一些可继承的函数。

BTAction:行为节点,继承于BTNode。具体的游戏逻辑应该放在这个节点里面。

BTPrecondition:节点的准入条件,每一个BTNode都会有一个。具体的游戏逻辑判断可以继承于它。

BTPrioritySelector:Priority Selector逻辑节点,继承于BTNode。每次执行,先有序地遍历子节点,然后执行符合准入条件的第一个子结点。可以看作是根据条件来选择一个子结点的选择器

BTSequence:Sequence逻辑节点,继承于BTNode。每次执行,有序地执行各个子结点,当一个子结点结束后才执行下一个。严格按照节点A、B、C的顺序执行,当最后的行为C结束后,BTSequence结束。

BTParallel:Parallel逻辑节点,继承于BTNode。同时执行各个子结点。每当任一子结点的准入条件失败,它就不会执行。

BTParallelFlexible:Parallel的一个变异,继承于BTNode。同时执行各个子节点。当所有子结点的准入条件都失败,它就不会执行。

BTTree:将所有节点组合起来的地方。

Database:黑板,一个存放共享数据的地方,可以看成是一个Key-Value的字典。为什么需要黑板呢?因为设计良好的行为逻辑,应该是独立的,可以在行为树的任何位置部署的。也就是说行为A和行为B并没有直接的沟通方法。黑板的作用就是作为一个行为树的“数据库”,让各个行为节点都可以储存数据进去,供感兴趣的行为节点利用。(同时,在Unity3d的语境下,Database继承MonoBehavior,可以提供各种Component给节点使用。)

UML类图:

image.png

四、行为树对于游戏的意义

如果没有可视化的编辑工具,如果没有artist能接手AI编辑,那么行为树的效果将大打折扣。因为行为树将耦合降低之后,如果没有可视化的编辑器调试工具,那么后人维护扩展这个模块的效率是很低的。比较明显的一点就是,调试BUG的时候,需要整个流程,各个可能会激活的节点都断好点,不然无法弄清整个流程。变成一段我最不希望看到的,只有调试才能知道结果的代码。所以这个成本需要设计人员仔细斟酌,如果要采用没有编辑器的行为树,应该怎么简化,怎么控制,且要想清楚对自己的游戏来说划不划算。
.
从业这几年来,面过的人中,大多都知道或者用过行为树。但当我询问行为树或者准确的说行为树的这种解决问题的思想,还能用在哪些地方的时候,大多答不上来,几乎都局限于做游戏AI。其实“行为树”(引号标注此处不特指行为树,而是行为树背后所包含的设计思想)对游戏的很多其他模块,都有借鉴的地方。游戏中复用情况较多、修改变化频繁的模块,都可以用上“行为树”。比如我们的新手引导模块,MMORPG的任务模块等,都可以用到“行为树”,来帮我们管控变化,加速模块的构建与迭代。

五、Tencent/behaviac

  • behaviac是游戏AI的开发框架组件,也是游戏原型的快速设计工具
  • 支持行为树BT,状态机FSM,HTN等多种范式
  • 方便的编辑,实时和离线调试
  • 支持全平台,适用于客户端和服务器,助力游戏快速迭代开发
  • 官方网站是文档,教程,API,FAQ,源码,下载等一切的入口
  • 您可以加入我们的QQ群433547396获得即时的帮助或者信息反馈。

六、magicsea behavior3go

golang behavior tree,from https://github.com/behavior3

作者:合肥黑
链接:https://www.jianshu.com/p/29cc3307d7ae
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

行为树 Behavior3go相关推荐

  1. behavior3go行为树节点类型介绍

    behavior3介绍 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.行为树节点类型 二.行为树节点Composites组合类说明 ​三.行为树节点Action ...

  2. 判断两个树是否相等和判断tree1是否包含tree2 python实现

    判断两个树是否相等 def equal(node_a, node_b):"""判断两个树是否相等:param node_a: :param node_b: :return ...

  3. 论文溯源树AMiner

    来自 DBLP.ArXiv.STM 等多家学术出版机构和平台的数据表明,在过去 20 年间,计算机科学.物理学.统计学等研究领域的出版物总量都有大幅增加.像 CVPR.AAAI 等有关人工智能等新兴领 ...

  4. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  5. 深度树匹配模型(TDM)

    深度树匹配模型(TDM) 算法介绍 Tree-based Deep Match(TDM)是由阿里妈妈精准定向广告算法团队自主研发,基于深度学习上的大规模(千万级+)推荐系统算法框架.在大规模推荐系统的 ...

  6. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  7. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  8. 线段树——HDU - 1698

    题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...

  9. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

最新文章

  1. SpringMVC4.x源码分析(五):request请求寻址HandlerMethod原理
  2. sqoop 基本使用
  3. C++ WINDOWS API 第1章 Windows 应用程序开发入门
  4. python识别图像数字诊断模块_opencv+python 机读卡识别
  5. php导出页面居中设置,PHPExcel导出插入图片和居中问题
  6. 服务器系统报错kernel-power,第十二讲、Linux服务器操作系统1.ppt
  7. java获取泛型的值_java 反射之获取泛型对象的所有字段与对应的值(包括父类的)...
  8. 哈工大大数据实验_【新闻动态】南京大学PASA大数据实验室在KDD Cup 2020 AutoGraph自动化图数据建模国际挑战赛中荣获第二名...
  9. Disabling Shortcut Keys in Full Screen mode
  10. ASP .NET CORE MVC 部署Windows 系统上 IIS具体步骤---.Net Core 部署到 IIS位系统中的步骤...
  11. Python和Matlab系统比较
  12. POI解析docx与doc文档中的难点归纳
  13. Android开发基础不牢?怒斩获了30家互联网公司offer,终局之战
  14. [线段树][数学]JZOJ 4237 Melancholy
  15. Promise 入门
  16. 实现一个div的背景颜色从左到右慢慢出现
  17. 第二章:Swagger2
  18. 手把手教你摆脱愚蠢的有道云笔记过上Typora的好日子
  19. React版TinyMCE富文本入坑
  20. java实验三_JAVA实验三及总结

热门文章

  1. 交互式数据可视化的7个主要优势
  2. C 结构体指针初始化
  3. nextval数组如何求解
  4. arm64 的ubutun20.04的wps及vscode,chrome的安装
  5. 基于sklearn随机森林算法探究肥胖的成因
  6. java内存释放_如何释放Java中的内存?
  7. js计算贷款金额怎么算
  8. Linux服务器综合练习
  9. 三星推出中国区代言人 能挽回中国市场吗?
  10. 星璨鸿途网红财富领路人,像“丁真”一样实力变现!