关于行为树(Behavior Tree)的理解。

前言

最近看到项目里有个行为树编辑器,然后就顺道看看这是个什么东西。然后看到挺多写行为树的都是关于Behavior Designer这个Unity插件的。而关于行为树(Behavior Tree)这个东西的描述就有点抽象。但为了搞清楚什么是行为树。然后我就下载了几个手写的行为树源码,比对下来也各有不同。感觉写的对我比较有帮助的是这个 点击跳转。
以下都是我对这些源码测试后对这个行为树的理解。我只说比较概念化的东西帮助理解。

行为树简介

行为树是一个包含逻辑节点和行为节点的树结构,每次需要找出一个行为的时候,会从树的根节点出发,遍历各个节点,找出第一个和当前数据相符合的行为。(这是比较正统的描述)
但我对几个手写版本的行为树测试之后,觉得这只是一种概念,就像面向对象一样。是个抽象的东西,只是定义了一种逻辑的组织和执行方式。而每个人运用的时候都是根据自己的理解来对这个定义进行实例。

行为树的结构

很多人都比较详细的描述过。我就简单的在描述一下我的理解。就是用树的结构。把一些节点连接起来。
最简单的例子:
根(根节点)——茎(子节点)——叶(子节点)
扩展1:
根(根节点)——茎(子节点)——茎(子节点)——叶(子节点)
扩展2:
根(根节点)——茎(子节点)
扩展3:
茎(子节点作为根节点)——叶(子节点)
那么我一个(根)根节点上引出五个茎(子节点)一个茎(子节点)再引出五个叶(子节点)也是可以的。
问题:茎和叶的描述都是子节点,有什么区别吗?结果是并没有什么区别。这么写只是对树的尊重。
所以,行为树其实就是组合一些定义好的节点。

关于节点

以下我只说一些比较通用的一些节点以及描述。
根节点
( 循环遍历子节点,只有某个成功或者完全失败才停止执行,只要有一个子节点处于runing的状态,便一直循环遍历该节点及其之前的节点。直到失败进入下一节点或者自己及之前节点有成功。)
顺序节点
(顺序依次执行每一个子行为,直到任意一个子节点失败返回失败或所有子节点都成功返回成功)
并行节点
(并行器:并行节点也会依次执行所有的子节点,无论子节点返回“成功”或“失败”都会继续运行后续节点,保证所有子节点都得到运行后在根据每个子节点的返回值来确定最终的返回结果。)
修饰节点
(给节点添加一些简单的通用逻辑,比如重复等)
行为节点
(物体具体执行的一些行为逻辑,同一时刻只能执行一个行为)
其实这些都是大家通用的定义好的一些节点。有人也会继续扩展一些等待节点或者阻断节点,都没什么问题,根据项目需要就可以。还有一些人对一些节点的定义理解也不同,例如:顺序节点(我的描述为,顺序依次执行每一个子行为,直到任意一个子节点失败返回失败或所有子节点都成功返回成功)那么有人的理解可能是这样(顺序遍历子节点,失败就继续,直到所有子节点都失败或者有节点执行成功。)
这样有什么问题吗?我觉得没什么问题。因为节点的逻辑都是自己定义的,效果符合自己的预期就Ok了。
说到底,就是把我们自己定义的节点组合起来。这就是为啥我要只说概念化的东西。

关于状态

行为树由多种不同类型的节点构成,有一个共同的核心功能,即它们会返回三种状态中的一个作为结果。这三种状态分别是:

成功-Success;失败-Failure;运行中-Running;

前两个,正如它们的名字,是用来向它们的父节点通知运行的成功或失败的结果。第三种是指还在运行中,结果还未决定,在下一个更新(tick)的时候再去检查这个节点的运行结果。

关于代码执行流程

这个其实也是一开始我比较困惑的地方。
但我测试了每个不同的节点作为根节点的情况之后。开始有所理解。
当然这个要结合上面的三种运行状态。
举个例子,就从最基本的三叉结构来说的。
关于行为树(Behavior Tree)的理解。_第1张图片如果根节点用原始的根节点,子节点1和子节点2分别用两个行为节点。
那么根据根节点的描述
( 循环遍历子节点,只有某个成功或者完全失败才停止执行,只要有一个子节点处于runing的状态,便一直循环遍历该节点及其之前的节点。直到失败进入下一节点或者自己及之前节点有成功。)
情况1:子节点1返回Success这组行为树逻辑结束。
情况2:或者子节点返回1Failure,继续看子节点2的状态。如果子节点2返回Failure,则达成完全失败返回Failure行为树逻辑结束。
情况3:如果子节点2返回Success,则达只有某个成功返回Success行为树逻辑结束。
那么如果节点1处于runing的状态呢?我们来到行为节点的描述:
(物体具体执行的一些行为逻辑,同一时刻只能执行一个行为)
情况4:节点1处于runing的状态,那么就要根据行为节点的逻辑。行为1执行直到返回Success(情况1,情况3)或者Failure(情况2)。
简单的执行流程如此,那么复杂的也是一样的,相当于这个三叉结构的嵌套。就是说子节点的运行逻辑是依托于父节点的定义的顺序。子节点自己的话执行自己的逻辑。
有些人会把这些根节点,顺序节点,并行节点 称为逻辑节点。因为它们的子节点会按照父节点定义的规则执行。也没什么问题,就是多了个概念。然后我还差点被误导,以为只有逻辑节点才能作为根节点。但其实单一的节点也是可以执行的。就像执行方法一样。只是单一执行的话再依托行为树有点杀鸡用牛刀了。

关于代码

这是我参考的代码。
参考1
参考2

主要是理解行为树的作用和使用需要重点关注的位置。后续可能会尝试一下如何做相关的编辑器。
但行为树这种概念,理解就行了。没什么好说的,AssetStore现成的插件用起来不香吗?不必重复造轮子。

你可能感兴趣的:(unity3d,行为树,Behavior,Tree)