行为树BT设计与实现

news/2024/4/29 13:40:05/文章来源:https://blog.csdn.net/qq_38880380/article/details/127270152

行为树BT设计与实现

  • 1 介绍
  • 2 汇总
    • From McYY
      • 整体结构
      • 运行逻辑
      • 节点共享数据
      • 中断的实现
    • From AKara
    • From Luyu Huang
    • From 阿高
    • From xiyoo0812
  • 参考

1 介绍

状态机与行为树BT

2 汇总

From McYY

lua行为树设计与实现
LuaBT

项目需要,之前行为树用的是behaviorDesigner,要改成纯lua的。先做了一版用递归实现,代码可读性高但是中断机制实现起来比较复杂,而且创建自定义action重写方法时需要调用父类的方法, 如果忘了调用就会出现问题, 所以改成了用栈模拟递归。

用栈模拟递归好处在于效率高,并且容易控制,用非递归实现后自定义一个行为树节点,那么该节点不用知道父亲的方法,只要做好自己的事情就OK了,完整测试工程已上传到了github:https://github.com/MCxYY/LuaBT

整体结构

在这里插入图片描述
在这里插入图片描述
其中BTManager存储着所有行为树BTree,unity每帧调用BTManager的Update,而BTManager调用所有运行中的BTree的Update,BTree管理着自身的节点Task,根据逻辑执行调用Task的OnAwake()、OnStart等
Shared是节点共享数据,在后文中讲述
Task的OnAwake是整颗行为树激活时运行一次
OnStart是进入该Task时运行一次
OnUpdate是该Task执行中时每帧运行一次
OnPause(bPause)是整棵行为树暂停或者从暂停中苏醒时运行,bPause为true则暂停
OnEnd()是该Task退出时运行一次

运行逻辑

行为树(BTree)启动的时候调用BTree.Init()方法先序遍历该树,获得一系列节点数据,比如赋值儿子index,每个节点的儿子index是什么,每个节点的父亲index等。
行为树(BTree)中存储着一个list<stack>,这个是运行栈,行为树启动时创建一个运行栈,塞进去树根;每当有并行分支,则创建一个运行栈,塞进去分支第一个运行的节点。

节点(Task)的状态有四种:
1、ETaskStatus.Inactive //未激活
2、ETaskStatus.Failure //失败
3、ETaskStatus.Success //成功
4、ETaskStatus.Running //运行中
运行栈中放的节点都是处于Running状态,update时遍历运行栈,取出栈顶节点执行,如果节点执行完毕后状态不等于running,说明该节点不需要再次运行,那么就出栈。

节点运行的时候
如果该节点是ParentTask类型则需要运行儿子,其状态由儿子执行完毕后的状态来决定;
如果该节点是Task类型没有儿子,那么其状态就是其Update的状态;

节点共享数据

节点共享数据分为三种:一,树之间任意节点全局共享的数据 二,树内任意节点共享的数据 三,节点内不共享数据
节点内数据那就不用说了,在节点内声明的数据都是节点内数据
BehaviorDesigner的共享数据是通过编辑器保存读取的
由于时间不允许,没有做编辑器,所以我就做了个存储的类简单的实现了下
Shared.lua就是存储的类,其实里面就是一个table,对外只提供一个GetData(name)的方法,如果没有name的变量就创建个值为空的table保存起来,返回这个table。之所以用table存,是因为table在lua中属于引用类型。

中断的实现

中断的实现应该是行为树中比较复杂的功能了,涉及到树上的一些算法及运行栈的操作,牵涉到的判断也多,这里会重点讲述。

中断必要的原因是可能存在以下情况(不限于此情况):
比如怪物正在向目标点移动的时候遇到玩家需要攻击,此时移动的节点状态是running,没有中断的时候只能走到目标点的时候返回success停止移动才开始进入其他节点,这时候就错过了攻击玩家,中断的作用就体现出来了,就算是在running状态也能打断运行栈进入攻击节点。
BehaviorDesigner打断的方法是将打断类型分为这么几类:
EAbortType = {
  None = 0, //不打断
  Self = 1, //打断自身
  LowerPriority = 2, //打断低优先级
  Both = 3, //同时包括Self和LowerPriority两种效果
}
其中只有Composite类型的节点可以拥有打断操作。
Self打断类型:指的是Composite节点下面的直系子孙(这个名词是我临时取得。。意思是Composite与Conditional中间可以插入Decorate,可以插入Composite但插入得Composite类型必须是Self或Both)Conditional类型的节点的状态发生变化时,那么打断正在运行且是Composite子孙的分支,重新进入变化的Conditional节点所处的分支中。打断的结构大概如下图所示:
在这里插入图片描述
(绿色的指正在运行中的节点)

From AKara

使用行为树(Behavior Tree)实现游戏AI

谈到游戏AI,很明显智能体拥有的知识条目越多,便显得更智能,但维护庞大数量的知识条目是个噩梦:使用有限状态机(FSM),分层有限状态机(HFSM),决策树(Decision Tree)来实现游戏AI总有那么些不顺意。试试Next-Gen AI的行为树(Behavior Tree)吧。
在这里插入图片描述
行为树(Behavior Tree)具有如下的特性:
有4大类型的Node:

  • Composite Node
  • Decorator Node
  • Condition Node
  • Action Node

任何Node被执行后,必须向其Parent Node报告执行结果:成功 / 失败。
这简单的成功 / 失败汇报原则被很巧妙地用于控制整棵树的决策方向。

From Luyu Huang

在这里插入图片描述
在笔者的项目中 NPC 要有自动化的行为, 例如怪物的巡逻, 寻敌和攻击, 宠物的跟随和战斗等. 完成这些需求最好的做法是使用行为树(Behavior Tree)。
行为树首先是一棵树, 它有着标准的树状结构: 每个结点有零个或多个子结点, 没有父结点的结点称为根结点, 每一个非根结点有且只有一个父结点。 在行为树中, 每个节点都可以被执行, 并且返回 Success, Failure 或 Running, 分别表示成功, 失败或正在运行。行为树会每隔一段时间执行一下根结点, 称为 tick。 当一个节点被执行时, 它往往会按照一定的规则执行自己的子节点, 然后又按照一定的规则根据子节点的返回在确定它自己的返回值。行为树通常有 4 种控制流节点(Sequence 节点, Fallback 节点, Parallel 节点和 Decorator 节点)和 2 种执行节点(动作节点和条件节点):

  • Sequence 节点(顺序
    每当 Sequence 节点被执行时, 它都会依次执行它的子节点, 直到有一个子节点返回 Failure 或 Running. Sequence 节点的返回值就是最后一个子节点的返回值。
    Sequence 节点有点像逻辑与的操作: 只有所有的节点返回成功它才返回成功。 我们通常用符号 “→” 表示 Sequence 节点.

  • Fallback 节点
    每当 Fallback 节点被执行时, 它都会依次执行它的子节点, 直到有一个子节点返回 Success 或 Running. Fallback 节点的返回值就是最后一个子节点的返回值。
    与 Sequence 节点相反, Fallback 节点有点像逻辑或的操作: 只要有一个节点返回成功它就返回成功. 我们通常用符号 “?” 表示 Fallback 节点。

  • Parallel 节点(并行
    每当 Parallel 节点被执行时, 它都会执行它所有的子节点。如果有至少 M 个节点返回 Success, Parallel 节点就返回 Success; 如果有至少 N - M + 1 个节点返回 Failure, Parallel 节点就返回 Failure, 这里 N 是其子节点的数量; 否则返回 Running。
    我们通常用符号 “⇉” 表示 Parallel 节点。

  • Decorator 节点(修饰
    有的时候会有一些特殊的需求, 需要用自己的方式执行子节点和处理其返回结果。 Decorator 节点就是为此而设计的, 它的行为都是自定义的. 可以说, Sequence, Fallback 和 Parallel 节点都是特殊的 Decorator 节点。 我们通常用 “δ” 表示 Decorator 节点。

  • 动作节点和条件节点
    一般来说, 动作节点和条件节点是行为树中的叶子节点, 它们都是根据具体需求具体实现的. 当动作节点被执行时, 它会执行一个具体的动作, 视情况返回 Success, Failure 或 Running. 当条件节点被执行时, 它会做一些条件判断, 返回 Success 或 Failure. 行为树并不关心一个节点具体做了什么事 – 是所谓的 “执行动作” 或是 “判断条件”, 所以说它们唯一的区别就是动作节点有可能会返回 Running 而条件节点不会。

  • 带记忆的控制流节点
    正如上面我们看到的, 控制流节点在每次 tick 的时候都会依次执行其所有的子节点并获取其返回值. 然而有时对于某些节点, 一旦执行了一次, 就不必再执行第二次了。 记忆节点便是用来解决这一问题的。在控制流节点中, Sequence 节点和 Fallback 节点可以是带记忆的. 当子节点返回 Success 或 Failure 时, 记忆节点总是会把返回值缓存起来; 一旦一个子节点的返回值被缓存了, 就不会执行这个子节点了, 而是直接取缓存中的值; 直到这个节点返回 Success 或 Failure, 便清空缓存。
    记忆节点有一些非常巧妙的应用. 我们通常在节点的右上角加上 * 号表示这个节点是记忆节点. 比如说记忆 Sequence 节点记作 “→∗”。

From 阿高

基于Unity行为树设计与实现的尝试
行为树的设计与实现

1、行为树只是单纯的一棵决策树,还是决策+控制树。为了防止不必要的麻烦,我目前设计成单纯的决策树。
2、什么时候执行行为树的问题,也就是行为树的 Tick 问题,是在条件变化的时候执行一次,还是只要对象激活,就在Update里面一直Tick。前者明显很节省开销,但那样设计的最终结果可能是最后陷入事件发送的泥潭中。那么一直Tick可能是最简单的办法,于是就引下面出新的问题。目前采用了一直Tick的办法。
3、基本上可以明显节点有 Composite Node、 Decorator Node、 Condition Node、 Action Node,但具体细节就很头疼。比如组合节点里的Sequence Node。这个节点是不是在每个Tick周期都从头迭代一次子节点,还是记录正在运行的子节点。每次都迭代子节点,就感觉开销有点大。记录运行节点就会出现条件冗余问题,具体后面再讨论。目前采用保存当前运行节点的办法。
4、条件节点(Condition Node)的位置问题。看到很多设计都是条件节点在最后才进行判断,而实际上,如果把条件放在组合节点处,就可以有效短路判断,不再往下迭代。于是我就采用了这种方法。
在这里插入图片描述
在这里插入图片描述

From xiyoo0812

参考

1、McYY–lua行为树设计与实现
2、MCxYY/LuaBT
3、使用行为树(Behavior Tree)实现游戏AI
4、行为树及其实现
5、基于Unity行为树设计与实现的尝试
6、【Godot】行为树(一)了解与设计行为树代码
7、xiyoo0812/luabt/–gitee
8、xiyoo0812/luabt/–github
9、xiyoo0812/luaoop

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_21967.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据科学的统计学知识笔记

1.描述统计 1.数字特征&#xff08;描述统计&#xff09; 集中趋势 众数中位数四分位数平均数&#xff1a;样本平均数&#xff08;xˉ\bar{x}xˉ&#xff09;与总体平均数&#xff08;μ\muμ&#xff09; 离中趋势&#xff08;离散趋势&#xff09;异众比率&#xff1a;非众…

scratch加法出题器 电子学会图形化编程scratch等级考试三级真题和答案解析2022年9月

目录 scratch加法出题器 一、题目要求 1、准备工作 2、功能实现 二、案例分析 <

『LeetCode|每日一题』---->二叉搜索树中第K小的元素

目录 1.每日一句 2.作者简介 3.二叉搜索树简介 『LeetCode|每日一题』二叉搜索树中第K小的元素 1.每日一题 4.解题思路 4.1 思路分析 4.2 核心代码 4.3 完整代码 4.4 运行结果 1.每日一句 因为时间永远分岔&#xff0c;通往无数的未来 2.作者简介 &#x1f3e1;个人主页&…

如何着手写一篇医学综述?

各位医学研究生&#xff0c;研0的时候是不是导师都已经把综述布置下来作为你的第一份作业呀&#xff1f;对于医学生们来说&#xff0c;不管你是本科就已经开始接触科研还是研究生开始才接触科研&#xff0c;反正在你开始阅读文献的时候开始一篇综述总是逃不过的。鉴于有综述任务…

Sql Server CDC配置

概述 CDC&#xff08;Change Data Capture&#xff09;&#xff0c;即数据变更抓取&#xff0c;通过为源端数据源开启CDC&#xff0c;ROMA Connect可实现数据源的实时数据同步以及数据表的物理删除同步。 本章节主要介绍如何为SQL Server数据库开启CDC功能。 前提条件 SQL S…

算力是新一代的“石油”,我们该如何利用好它?

我们处在一个数字世界&#xff0c;计算能力成为科技进步和经济发展的底座&#xff0c;也正在改变我们的生产方式和生活方式。未来&#xff0c;几万台、几十万台甚至几亿台服务器&#xff0c;如果都能够基于一个操作系统进实时调度&#xff0c;将带来巨大的算力提升。我们这一代…

【Linux高效小trick】快速查看Linux进程的开始和运行时间

写在前面 前面介绍了&#xff0c;怎么杀死Linux的僵尸进程&#xff0c;为GPU释放更多的内存&#xff0c;做想做的事&#xff0c;文章链接如下&#xff1a; 【Linux高效小trick】Linux下杀死僵尸进程&#xff0c;释放GPU内存&#xff0c;让代码全速运行~ 今天再来具体说下&…

Jetpack 之 ViewModel

Jetpack 系列第三篇&#xff0c;这次回顾 ViewModel&#xff0c;ViewModel 作为 MVVM 架构中的 VM 层&#xff0c;具有自己的生命周期&#xff0c;且生命周期贯穿整个 Activity 或 Fragment&#xff0c;相较于之前 MVP 的 Presenter&#xff0c;它的存活时间更长&#xff0c;所…

商用图片素材,高清无水印

今天给大家分享8个免费、商用图片素材网站&#xff0c;全部高清无水印&#xff0c;轻松应对各种场景。1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx菜鸟图库是一个综合性素材网站&#xff0c;这里面有很多设计、图片、视频、音频等素材&#xff0c;图片素材全部都…

vscode 提示 vetur can‘t find `tsconfig.json`的解决办法

VSCode&#xff08;全称&#xff1a;Visual Studio Code&#xff09;是一款由微软开发且跨平台的免费源代码编辑器。该软件支持语法高亮、代码自动补全&#xff08;又称 IntelliSense&#xff09;、代码重构、查看定义功能&#xff0c;并且内置了命令行工具和 Git 版本控制系统…

SEO作弊有哪些手段,网站采用SEO作弊会带来哪些惩罚

在做网站SEO优化过程中&#xff0c;有的人为了快速提高网站排名&#xff0c;采用了各种各样的方法。有的甚至采用SEO作弊的手段来优化网站&#xff0c;短期内提升了网站的排名。但是&#xff0c;我们要知道&#xff0c;做SEO优化欲速则不达&#xff0c;SEO作弊会给网站带来一定…

部署CentOS可视化界面GUI-之腾讯云服务器

目录 一、购买云服务器实例 二、配置安全组、设置管理员密码 三、远程登录 四、安装CentOS可视化界面GUI 4.1、系统GUI配置 4.2、系统GUI配置 一、购买云服务器实例 二、配置安全组、设置管理员密码 三、远程登录 用其控制台下webShell&#xff0c;或VNC模式&#xff0…

《MySQL实战45讲》——学习笔记08 “一致性视图、可重复读实现“

这篇文章讲的比较分散&#xff0c;这里做一个梳理&#xff0c;先将简单的概念如"事务的启动时机"、"视图"、"秒级创建快照"拎出来解释&#xff0c;然后通过文章中的几个例子说明"一致性读"和"当前读"&#xff1b; 08 | …

AspectJ in action

Discovering AOP This chapter covers ■ Understanding crosscutting concerns ■ Modularizing crosscutting concerns using AOP ■ Understanding AOP languages Reflect back on your last project, and compare it with a project you worked on a few years back. Wha…

一文带你快速鉴别CookieSession

文章目录会话跟踪技术1、相关基础概念2、Cookie2.1 Cookie的基本使用2.1.1 发送Cookie2.1.2 获取Cookie2.2 Cookie原理2.3 Cookie存活时间2.4 Cookie存储中文3、Session3.1 Session的基本使用3.2 Session原理3.3 Session的钝化和活化3.4 Session的存活时间总结会话跟踪技术 1、…

SSl证书协议作用

SSl证书协议作用 随着移动互联网时代的飞速发展&#xff0c;似乎每周都能看到很多关于数据泄露的新闻&#xff0c;而且报道还在不断涌现。在统计的100款app中&#xff0c;有多达91款app收集了过多的用户个人信息。 为了改善这一现象&#xff0c;网络空间管理局联合发布了《认定…

TRC丨艾美捷TRC 2-氨基-2-甲基丙酰胺说明书

艾美捷TRC 2-氨基-2-甲基丙酰胺化学性质&#xff1a; 目录号A010210 化学名称2-氨基-2-甲基丙酰胺 CAS 编号16252-90-7 分子式C₄H₁₀N2O 外貌白色固体 熔点>250C&#xff08;分解&#xff09; 分子量102.14 溶解度甲醇&#xff08;少量&#xff09; 类别建筑模块…

听说2022金九银十变成铜九铁十了......

往年的金九银十&#xff0c;今年被戏称为“铜九铁十”。知名的大厂HR们都在不断的裁员&#xff0c;能被保住不被裁掉可能就万事大吉了&#xff0c;赛道越来越窄&#xff0c;都在预测未来计算机行业是不是下一个土木工程&#xff1f; 我也算是软件测试岗位的老鸟了&#xff0c;…

计算机网络03之可靠传输

1. 停止等待协议 1.概述 发送方每次只能发送一个数据包&#xff0c;确认方每次只能发送一个确认。发送方收到重复的确认会丢弃&#xff08;接收方已经接收&#xff09;&#xff0c;接收方收到重复的数据&#xff0c;会把数据丢弃&#xff0c;但是会发送确认&#xff08;防止上…

DETR:End-to-End Object Detection with Transformers

论文地址&#xff1a;https://arxiv.org/abs/2005.12872 代码地址&#xff1a;https://github.com/facebookresearch/detr 在看完Transformer之后&#xff0c;将会开始看视觉类的Transformer应用。本篇论文出自ECCV20&#xff0c;是关于目标检测的论文。DETR&#xff0c;即Det…