行为树的理解和学习

最近打算好好研究一下行为树,在使用行为树之前,我们应该先理解行为树的基本概念和相关的逻辑,然后我们就Unity3D平台下的行为树插件的使用来进行学习行为树。

什么是行为树

如果了解过状态机,会知道在行为树之前,在实现AI用得比较多的技术是状态机,状态机理解起来是比较简单的,即一个状态过渡到另一个状态,通过判断将角色的状态改变即可,如果学习过Unity的Mecanim动画系统,会更加直观的理解。

但是状态机在状态较多的情况下会使状态之间的切换变得异常繁琐,同时状态之间很难复用。

在这种情况下,行为树被发明出来,行为树的优点如下:

  1. 行为树提供大量的流程控制方法,使得状态之间的改变更加直观;
  2. 整个游戏AI使用树型结构,方便查看与编辑;
  3. 方便调试和代码编写;
  4. 最重要的:行为树方便制作编辑器,可以交由策划人员使用;

行为树相关资料

这里给出我知道的行为树相关的资料,大家有更好的资料希望可以告诉我:

AI分享站

腾讯游戏行为树框架:支持C++、C#(Unity3D)

其中,腾讯的开源项目提供了C#编写的行为树编辑器源码和不错的相关文档(中文的哦),非常具有学习价值。

行为树原理

行为树是一种树形结构,所以其可以分成3种节点类型:

(画丑了点,见谅...)

  1. 红色的节点:根节点,没有父节点的节点;
  2. 蓝色的节点:组合节点,有父节点和子节点的节点;
  3. 白色的节点:叶节点,没有子节点的节点;

而编号为深度优先访问的顺序;

节点的返回

每个节点都会有一个返回值,可能出现的返回值有3个,如下:

  • 运行中:表示当前节点还在运行中,下一次调用行为树时任然运行当前节点;
  • 失败:表示当前节点运行失败;
  • 成功:表示当前节点运行成功;

下面我们来细说一下这几个节点;

根节点

行为树的入口节点,可以是任意类型的节点;

组合节点

行为树的组合节点是由下面几种类型来组成的:

选择节点/优先选择节点(Selector)

该节点会从左到右的依次执行其子节点,只要子节点返回“失败”,就继续执行后面的节点,直到有一个节点返回“运行中”或“成功”时,会停止后续节点的运行,并且向父节点返回“运行中”或“成功”,如果所有子节点都返回“失败”则向父节点返回“失败”。

随机选择节点(Random Selector)

之前的选择节点是有优先级顺序的,而随机选择节点的执行顺序是随机的。但每个节点只会执行一次,比如包含子节点:A、B、C、D、E;使用随机选择节点,执行顺序可能是:D、E、A、C、B或其他组合。其它规则同选择节点一致。

顺序节点(Sequence)

该节点会从左到右的依次执行其子节点,只要子节点返回“成功”,就继续执行后面的节点,直到有一个节点返回“运行中”或“失败”时,会停止后续节点的运行,并且向父节点返回“运行中”或“失败”,如果所有子节点都返回“成功”则向父节点返回“成功”。

修饰节点(Decorator)

修饰节点只包含一个子节点,用来以某种方式来改变这个子节点的行为。

修饰节点的类型比较多,这里我们说一些比较常见的修饰节点:

Until Success和Until Failure

循环执行子节点,直到返回“成功”或“失败”为止。

比如Until Success在子节点返回“运行中”和“失败”时都会向父节点返回“运行中”,返回“成功”时向父节点返回“成功”。

Until Failure在子节点返回“运行中”和“成功”时都会向父节点返回“运行中”,返回“失败”时向父节点返回“成功”。

Limit

执行子节点一定次数后强制返回“失败”。

当子节点运行指定次数后还没有返回“失败”则该节点向父节点返回失败。

Timer

子节点不会立即执行,而会在指定的时间到达后才开始执行。

TimeLimit

指定子节点的最长运行时间,如果子节点在指定时间到达后还在运行则强制返回“失败”。

Invert

对子节点的返回结果取“非”,即子节点返回“成功”则该节点返回“失败”,子节点返回“失败”则该节点返回成功。

并行节点(Parallel)

不同于选择和顺序节点依次执行每个节点,并行节点是“同时”执行所有的节点,然后根据所有节点的返回值判断最终返回的结果。

这里的“同时”会迷惑住不少人,实际上,行为树是运行在单一线程上的,并不会在并行节点上开多个线程来进行真正的同时执行,那么“同时”的含义是什么?

我们知道选择或顺序节点会依次执行所有的子节点,当子节点返回“成功”或“失败”后就会停止后续节点的执行,而并行节点也会依次执行所有的子节点,无论子节点返回“成功”或“失败”都会继续运行后续节点,保证所有子节点都得到运行后在根据每个子节点的返回值来确定最终的返回结果。

并行节点一般可以设定退出该节点的条件,比如:

  • 当全部节点都返回成功时退出;
  • 当某一个节点返回成功时退出;
  • 当全部节点都返回成功或失败时退出;
  • 当某一个节点返回成功或失败时退出;
  • 当全部节点都返回失败时退出;
  • 当某一个节点返回失败时退出;

叶节点

条件节点(Condition)

条件节点可以理解为一个if判断语句,当条件的测试结果为true时向父节点传递success,结果为false时向父节点传递failure;

该节点搭配一些组合节点可以完成各种判断跳转,比如搭配顺序节点,可以做出“是否看见敌人”->“向敌人开火”的AI;

行为节点(Action)

行为节点用来完成具体的操作,比如,移动到目标点,执行开火等代码逻辑,多种情况下行为节点会返回running和success;

行为节点也可能会使用多帧来完成;

子树的复用

我们设计好的行为树可以在其他树中作为一颗子树来进行使用,最大可能的复用子树可以减少开发量。

行为树和状态机的选择

行为树并不能完全的替代状态机,两者都可以用来处理AI编写问题,但行为树是“轮询”机制,而状态机是“事件”机制,在最终使用之前一定要好好权衡和选择才行。

时间: 2024-10-10 11:09:03

行为树的理解和学习的相关文章

线段树入门理解

在复习算法至分治法时,书本上主要介绍了合并排序和快速排序,较为简单.特拓展简单学习一个应用了分治法的算法结构--线段树. acm刷题时遇到许多连续区间的动态查询问题,例如求取某一区间上元素之和.求取某一区间上元素的最大值,此时如果使用一般的方法求解会使得时间超出要求.此时需要使用到线段树,其主要用于高效解决连续区间的动态查询问题. 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN),从而大大减少耗时

Linux系统的理解及学习Linux内核的心得

作业列表      linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作 linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码 linux内核分析作业3:跟踪分析Linux内核的启动过程 linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 linux内核分析作业5:分析system_call中断处理过程 linux内核分析作业6:分析Linux内核创建一个新进程的过程 Linux内核分析作业7:L

最长回文字串理解(学习Manacher's algorithm)

关于字符串的子串问题,我们经常需要利用的是已经访问的部分的信息,来降低复杂度,和提高效率:在求最长回文子串的问题中,Manacher's algorithm提供了一种很好的机制,虽然部分地方不太容易理解 先说下核心的思想:先对原字符串进行预处理,将字符串"abc"转换为"$#a#b#c#"的形式,既避免了访问越界的问题,又保证每一个字符有至少一个对称的串(真字符,或是假的“#”) 预留两对变量(当前得到的中心位置“center”,和字符串右侧最远位置“R”,以及对称

利用Theano理解深度学习——Multilayer Perceptron

一.多层感知机MLP 1.MLP概述 对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logistic回归分类器,这个特殊的Logistic回归分类器首先通过一个非线性变换Φ(non-linear transformation)对样本的输入进行非线性变换,然后将变换后的值作为Logistic回归的输入.非线性变换的目的是将输入的样本映射到一个空间,在该空间中,这些样本是线性可分的.这个中间层

Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树2 1.4. 满二叉树和完全二叉树..完全二叉树说明深度达到完全了.2 1.5. 属的逻辑表示 树形比奥死,括号表示,文氏图,凹镜法表示3 1.6. 二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构.3 1.6.1. 3.2 平衡二叉

关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)

关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)   作者:王可利(Star·星星) HTML中 相对定位:position:relative; 绝对定位:position:absolut; 1.相对定位(div与div之间的关系)        body 标签其实就是一个大的盒子,在body里面设置 两个盒子div1 和 div2 ,而且两个盒子都给了它一个相对定位:position:relative;,那么div2 就会相对于 div1 排版,排在div1的下面,

cocos creator 002 场景树 Node 的属性 学习

场景树 Node 的属性 学习 cc.Class Onload 读取 node的各种属性 读取 修改 自定义自己的属性 读取修改 start 中 自定义自己的方法 自定义自己的属性在 properties 中 添加自定义属性直接在面板上修改 自定义属性 如果不想显示 内部变量 则前面加 下划线 _ 内部函数 _test() 或者专门设置一个车 ctro(){} 处理自定义属性,方法 -> PPT 访问父亲 this.node.parent.name --> Canvas访问孩子 this.no

干货 | 深入理解深度学习中的激活函数

理解深度学习中的激活函数 在这个文章中,我们将会了解几种不同的激活函数,同时也会了解到哪个激活函数优于其他的激活函数,以及各个激活函数的优缺点. 1. 什么是激活函数? 生物神经网络是人工神经网络的起源.然而,人工神经网络(ANNs)的工作机制与大脑的工作机制并不是十分的相似.不过在我们了解为什么把激活函数应用在人工神经网络中之前,了解一下激活函数与生物神经网络的关联依然是十分有用的. 一个典型神经元的物理结构由细胞体.向其他神经元发送信息的轴突以及从其他神经元接受信号或信息的树突组成. ? 图

torchvision的理解和学习 加载常用数据集,对主流模型的调用.md

torchvision的理解和学习 加载常用数据集,对主流模型的调用 https://blog.csdn.net/tsq292978891/article/details/79403617 加载常用数据集,对主流模型的调用 原文地址:https://www.cnblogs.com/lishikai/p/12364671.html