[Unity插件]Lua行为树(七):行为树嵌套
在上一篇的基础上,可以测试下行为树的嵌套,所谓的行为树嵌套,就是在一棵行为树下的某一个分支,接入另一棵行为树。
以下面这棵行为树为例:
TestBehaviorTree2.lua
- TestBehaviorTree2 = BTBehaviorTree:New();
- local this = TestBehaviorTree2;
- this.name = "TestBehaviorTree2";
- function this:New()
- local o = {};
- setmetatable(o, self);
- self.__index = self;
- self:Init();
- return o;
- end
- function this:Init()
- local repeater = BTRepeater:New();
- local sequence = BTSequence:New();
- local log = BTLog:New("This is a other tree!!!");
- local log2 = BTLog:New("This is a other tree 2!!!");
- self:SetStartTask(repeater);
- repeater:AddChild(sequence);
- sequence:AddChild(log);
- sequence:AddChild(log2);
- end
TestBehaviorTree.lua
- TestBehaviorTree = BTBehaviorTree:New();
- local this = TestBehaviorTree;
- this.name = "TestBehaviorTree";
- function this:New()
- local o = {};
- setmetatable(o, self);
- self.__index = self;
- self:Init();
- return o;
- end
- function this:Init()
- local repeater = BTRepeater:New();
- local selector = BTSelector:New();
- local sequence = BTSequence:New();
- local isNullOrEmpty = BTIsNullOrEmpty:New("");
- local log = BTLog:New("This is a empty string!!!");
- local tree2 = TestBehaviorTree2:New();
- self:SetStartTask(repeater);
- repeater:AddChild(selector);
- selector:AddChild(sequence);
- selector:AddChild(tree2);
- sequence:AddChild(isNullOrEmpty);
- sequence:AddChild(log);
- end
打印如下:
上面的执行结果是没有问题的,由此可见,将BTBehaviorTree当作节点,然后嵌套在行为树中是可行的。不过通过上面的打印,可以发现嵌套树先被打印,然后总树才被打印,而且嵌套树的层级也是不对的。
对于打印错误,这是节点添加顺序造成的问题,因此不应该在设置节点或者添加节点时进行打印,应该在整棵数构成完成后进行打印。
对于层级不对,可以在添加嵌套树后更新嵌套树下的节点层级。
Enum.lua
- --节点状态
- BTTaskStatus = {
- Inactive = , --尚未执行
- Failure = , --返回失败
- Success = , --返回成功
- Running = , --执行中
- }
- --节点类型
- BTTaskType = {
- Root = ,
- Action = ,
- Composite = ,
- Conditional = ,
- Decorator = ,
- }
BTBehaviorManager.lua
- BTBehaviorManager = {};
- local this = BTBehaviorManager;
- this.printTreeStr = "";
- function this.RunTree(tree)
- this.bTree = tree;
- this.OnUpdate();
- end
- function this.OnUpdate()
- local status = this.bTree:OnUpdate();
- while (status == BTTaskStatus.Running) do
- status = this.bTree:OnUpdate();
- end
- end
- --深度优先,打印树结构
- function this.PrintTree(task)
- this.printTreeStr = "";
- this.AddToPrintTreeStr(task);
- print(this.printTreeStr);
- end
- function this.AddToPrintTreeStr(task)
- local taskType = task.taskType;
- this.printTreeStr = this.printTreeStr .. task:ToString() .. "\n";
- if (taskType == BTTaskType.Root) then
- this.AddToPrintTreeStr(task.startTask);
- elseif (taskType == BTTaskType.Composite or taskType == BTTaskType.Decorator) then
- for i=,#task.childTasks do
- this.AddToPrintTreeStr(task.childTasks[i]);
- end
- else
- end
- end
BTBehaviorTree.lua
- --[[
- 树的根节点
- --]]
- BTBehaviorTree = BTTask:New();
- local this = BTBehaviorTree;
- this.taskType = BTTaskType.Root;
- function this:New()
- local o = {};
- setmetatable(o, self);
- self.__index = self;
- return o;
- end
- --设置起始节点
- function this:SetStartTask(task)
- task.root = self;
- task.parent = self;
- task.layer = self.layer + ;
- self.startTask = task;
- end
- --更新子节点层级
- function this:UpdateLayer()
- self:UpdateChildLayer(self.startTask);
- end
- function this:UpdateChildLayer(task)
- local taskType = task.taskType;
- task.layer = task.root.layer + task.layer - ;
- if (taskType == BTTaskType.Root) then
- self:UpdateChildLayer(task.startTask);
- elseif (taskType == BTTaskType.Composite or taskType == BTTaskType.Decorator) then
- for i=,#task.childTasks do
- self:UpdateChildLayer(task.childTasks[i]);
- end
- else
- end
- end
- function this:OnUpdate()
- if (self.startTask) then
- return self.startTask:OnUpdate();
- end
- end
打印如下:
[Unity插件]Lua行为树(七):行为树嵌套的更多相关文章
- [Unity插件]Lua行为树(一):BehaviorDesigner源码分析
BehaviorDesigner是Unity上的一款行为树插件,不过这个插件是用C#编写的,编写出来的行为树也是依赖于C#的,不利于热更,所以有必要写一个lua版本的. 首先下载BehaviorDes ...
- [Unity插件]Lua行为树(十二):行为树管理
之前运行的行为树,都是一颗总树,那么实际上会有很多的总树,因此需要对行为树进行管理. BTBehaviorManager.lua BTBehaviorManager = {}; local this ...
- [Unity插件]Lua行为树(六):打印树结构
经过前面的文章,已经把行为树中的四种基本类型节点介绍了下.接下来可以整理一下,打印一下整棵行为树.注意点如下: 1.可以把BTBehaviorTree也当作一种节点,这样就可以方便地进行行为树嵌套了 ...
- [Unity插件]Lua行为树(四):条件节点和行为节点
条件节点和行为节点,这两种节点本身的设计比较简单,项目中编写行为树节点一般就是扩展这两种节点,而Decorator和Composite节点只需要使用内置的就足够了. 它们的继承关系如下: Condit ...
- [Unity插件]Lua行为树(二):树结构
参考链接:https://blog.csdn.net/u012740992/article/details/79366251 在行为树中,有四种最基本的节点,其继承结构如下: Action->T ...
- [Unity插件]Lua行为树(三):组合节点Sequence
Sequence的继承关系如下: Sequence->Composite->ParentTask->Task 上一篇已经实现了简单版本的ParentTask和Task(基于Behav ...
- [Unity插件]Lua行为树(十一):组合节点Parallel
Parallel节点类似Sequence节点,不同在于Parallel会每帧执行所有的节点.当所有节点返回成功时返回成功,当其中一个节点返回失败时,返回失败并且结束所有的子节点运行. 例如说,给Seq ...
- [Unity插件]Lua行为树(十):通用行为和通用条件节点
在行为树中,需要扩展的主要是行为节点和条件节点.一般来说,每当要创建一个节点时,就要新建一个节点文件.而对于一些简单的行为节点和条件节点,为了去掉新建文件的过程,可以写一个通用版本的行为节点和条件节点 ...
- [Unity插件]Lua行为树(九):条件节点调整
先看一下之前的条件节点是怎么设计的: BTConditional.lua BTConditional = BTTask:New(); local this = BTConditional; this. ...
随机推荐
- Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering
<Windows Azure Platform 系列文章目录> 在有些时候,我们需要通过VNet Peering,把两个虚拟网络通过内网互通互联.比如: 1.在订阅A里的Virtual N ...
- 【maven】之使用import scope解决maven继承(单)问题
想必大家在做SpringBoot应用的时候,都会有如下代码: <parent> <groupId>org.springframework.boot</groupId> ...
- Android keystore相关
一.生成keystorekeytool -genkey -alias test.keystore -keyalg RSA -validity -keystore test.keystore 二.查看 ...
- 【HTTP】使用 RestTemplete 实现 post请求
如上图,要求: post请求; x-www-form-urlencoded 类型; 如下代码没有进行整理,但是测试OK package com.chinamobile.epic.http; impor ...
- Guiceberry+Webdriver+TestNG
1. Guiceberry Leverage Guice to achieve Dependency Injection on your JUnit tests https://code.google ...
- bzoj5017: [Snoi2017]炸弹
Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...
- Web jsp开发学习——新建一个项目
然后 index.jsp编辑 新建一个servlet 准备发布 发布
- 使用Softmax回归将神经网络输出转成概率分布
神经网络解决多分类问题最常用的方法是设置n个输出节点,其中n为类别的个数.对于每一个样例,神经网络可以得到一个n维数组作为输出结果.数组中的每一个维度(也就是每一个输出节点)对应一个类别,通过前向传播 ...
- HTML代码优化中SEO要注意哪些细节
本文来源于学业无忧网,转载请保留:http://www.ixywy.com/ 这段时间,我们翻阅了一些同行撰写的书.其中,几乎每本书都存在问题.这个肯定在所难免,但是作为一名职业的SEO更应该注意一些 ...
- 在Linux里安装Samba(文件共享)方便在Windows下面操作
第一步:安装包 在CentOS是 yum install samba 在Ubuntu是 apt install samba 第二步:添加用户 adduser 用户名 smbpasswd -a 用户名 ...