在上一篇的基础上,可以测试下行为树的嵌套,所谓的行为树嵌套,就是在一棵行为树下的某一个分支,接入另一棵行为树。

以下面这棵行为树为例:

TestBehaviorTree2.lua

  1. TestBehaviorTree2 = BTBehaviorTree:New();
  2.  
  3. local this = TestBehaviorTree2;
  4. this.name = "TestBehaviorTree2";
  5.  
  6. function this:New()
  7. local o = {};
  8. setmetatable(o, self);
  9. self.__index = self;
  10. self:Init();
  11. return o;
  12. end
  13.  
  14. function this:Init()
  15. local repeater = BTRepeater:New();
  16. local sequence = BTSequence:New();
  17. local log = BTLog:New("This is a other tree!!!");
  18. local log2 = BTLog:New("This is a other tree 2!!!");
  19.  
  20. self:SetStartTask(repeater);
  21.  
  22. repeater:AddChild(sequence);
  23.  
  24. sequence:AddChild(log);
  25. sequence:AddChild(log2);
  26. end

TestBehaviorTree.lua

  1. TestBehaviorTree = BTBehaviorTree:New();
  2.  
  3. local this = TestBehaviorTree;
  4. this.name = "TestBehaviorTree";
  5.  
  6. function this:New()
  7. local o = {};
  8. setmetatable(o, self);
  9. self.__index = self;
  10. self:Init();
  11. return o;
  12. end
  13.  
  14. function this:Init()
  15. local repeater = BTRepeater:New();
  16. local selector = BTSelector:New();
  17. local sequence = BTSequence:New();
  18. local isNullOrEmpty = BTIsNullOrEmpty:New("");
  19. local log = BTLog:New("This is a empty string!!!");
  20. local tree2 = TestBehaviorTree2:New();
  21.  
  22. self:SetStartTask(repeater);
  23.  
  24. repeater:AddChild(selector);
  25.  
  26. selector:AddChild(sequence);
  27. selector:AddChild(tree2);
  28.  
  29. sequence:AddChild(isNullOrEmpty);
  30. sequence:AddChild(log);
  31. end

打印如下:

上面的执行结果是没有问题的,由此可见,将BTBehaviorTree当作节点,然后嵌套在行为树中是可行的。不过通过上面的打印,可以发现嵌套树先被打印,然后总树才被打印,而且嵌套树的层级也是不对的。

对于打印错误,这是节点添加顺序造成的问题,因此不应该在设置节点或者添加节点时进行打印,应该在整棵数构成完成后进行打印。

对于层级不对,可以在添加嵌套树后更新嵌套树下的节点层级。

Enum.lua

  1. --节点状态
  2. BTTaskStatus = {
  3. Inactive = , --尚未执行
  4. Failure = , --返回失败
  5. Success = , --返回成功
  6. Running = , --执行中
  7. }
  8.  
  9. --节点类型
  10. BTTaskType = {
  11. Root = ,
  12. Action = ,
  13. Composite = ,
  14. Conditional = ,
  15. Decorator = ,
  16. }

BTBehaviorManager.lua

  1. BTBehaviorManager = {};
  2.  
  3. local this = BTBehaviorManager;
  4. this.printTreeStr = "";
  5.  
  6. function this.RunTree(tree)
  7. this.bTree = tree;
  8. this.OnUpdate();
  9. end
  10.  
  11. function this.OnUpdate()
  12. local status = this.bTree:OnUpdate();
  13. while (status == BTTaskStatus.Running) do
  14. status = this.bTree:OnUpdate();
  15. end
  16. end
  17.  
  18. --深度优先,打印树结构
  19. function this.PrintTree(task)
  20. this.printTreeStr = "";
  21. this.AddToPrintTreeStr(task);
  22. print(this.printTreeStr);
  23. end
  24.  
  25. function this.AddToPrintTreeStr(task)
  26. local taskType = task.taskType;
  27.  
  28. this.printTreeStr = this.printTreeStr .. task:ToString() .. "\n";
  29.  
  30. if (taskType == BTTaskType.Root) then
  31. this.AddToPrintTreeStr(task.startTask);
  32. elseif (taskType == BTTaskType.Composite or taskType == BTTaskType.Decorator) then
  33. for i=,#task.childTasks do
  34. this.AddToPrintTreeStr(task.childTasks[i]);
  35. end
  36. else
  37.  
  38. end
  39. end

BTBehaviorTree.lua

  1. --[[
  2. 树的根节点
  3. --]]
  4. BTBehaviorTree = BTTask:New();
  5.  
  6. local this = BTBehaviorTree;
  7. this.taskType = BTTaskType.Root;
  8.  
  9. function this:New()
  10. local o = {};
  11. setmetatable(o, self);
  12. self.__index = self;
  13. return o;
  14. end
  15.  
  16. --设置起始节点
  17. function this:SetStartTask(task)
  18. task.root = self;
  19. task.parent = self;
  20. task.layer = self.layer + ;
  21. self.startTask = task;
  22. end
  23.  
  24. --更新子节点层级
  25. function this:UpdateLayer()
  26. self:UpdateChildLayer(self.startTask);
  27. end
  28.  
  29. function this:UpdateChildLayer(task)
  30. local taskType = task.taskType;
  31. task.layer = task.root.layer + task.layer - ;
  32.  
  33. if (taskType == BTTaskType.Root) then
  34. self:UpdateChildLayer(task.startTask);
  35. elseif (taskType == BTTaskType.Composite or taskType == BTTaskType.Decorator) then
  36. for i=,#task.childTasks do
  37. self:UpdateChildLayer(task.childTasks[i]);
  38. end
  39. else
  40.  
  41. end
  42. end
  43.  
  44. function this:OnUpdate()
  45. if (self.startTask) then
  46. return self.startTask:OnUpdate();
  47. end
  48. end

打印如下:

[Unity插件]Lua行为树(七):行为树嵌套的更多相关文章

  1. [Unity插件]Lua行为树(一):BehaviorDesigner源码分析

    BehaviorDesigner是Unity上的一款行为树插件,不过这个插件是用C#编写的,编写出来的行为树也是依赖于C#的,不利于热更,所以有必要写一个lua版本的. 首先下载BehaviorDes ...

  2. [Unity插件]Lua行为树(十二):行为树管理

    之前运行的行为树,都是一颗总树,那么实际上会有很多的总树,因此需要对行为树进行管理. BTBehaviorManager.lua BTBehaviorManager = {}; local this ...

  3. [Unity插件]Lua行为树(六):打印树结构

    经过前面的文章,已经把行为树中的四种基本类型节点介绍了下.接下来可以整理一下,打印一下整棵行为树.注意点如下: 1.可以把BTBehaviorTree也当作一种节点,这样就可以方便地进行行为树嵌套了 ...

  4. [Unity插件]Lua行为树(四):条件节点和行为节点

    条件节点和行为节点,这两种节点本身的设计比较简单,项目中编写行为树节点一般就是扩展这两种节点,而Decorator和Composite节点只需要使用内置的就足够了. 它们的继承关系如下: Condit ...

  5. [Unity插件]Lua行为树(二):树结构

    参考链接:https://blog.csdn.net/u012740992/article/details/79366251 在行为树中,有四种最基本的节点,其继承结构如下: Action->T ...

  6. [Unity插件]Lua行为树(三):组合节点Sequence

    Sequence的继承关系如下: Sequence->Composite->ParentTask->Task 上一篇已经实现了简单版本的ParentTask和Task(基于Behav ...

  7. [Unity插件]Lua行为树(十一):组合节点Parallel

    Parallel节点类似Sequence节点,不同在于Parallel会每帧执行所有的节点.当所有节点返回成功时返回成功,当其中一个节点返回失败时,返回失败并且结束所有的子节点运行. 例如说,给Seq ...

  8. [Unity插件]Lua行为树(十):通用行为和通用条件节点

    在行为树中,需要扩展的主要是行为节点和条件节点.一般来说,每当要创建一个节点时,就要新建一个节点文件.而对于一些简单的行为节点和条件节点,为了去掉新建文件的过程,可以写一个通用版本的行为节点和条件节点 ...

  9. [Unity插件]Lua行为树(九):条件节点调整

    先看一下之前的条件节点是怎么设计的: BTConditional.lua BTConditional = BTTask:New(); local this = BTConditional; this. ...

随机推荐

  1. Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering

    <Windows Azure Platform 系列文章目录> 在有些时候,我们需要通过VNet Peering,把两个虚拟网络通过内网互通互联.比如: 1.在订阅A里的Virtual N ...

  2. 【maven】之使用import scope解决maven继承(单)问题

    想必大家在做SpringBoot应用的时候,都会有如下代码: <parent> <groupId>org.springframework.boot</groupId> ...

  3. Android keystore相关

    一.生成keystorekeytool -genkey -alias test.keystore -keyalg RSA -validity -keystore test.keystore 二.查看 ...

  4. 【HTTP】使用 RestTemplete 实现 post请求

    如上图,要求: post请求; x-www-form-urlencoded 类型; 如下代码没有进行整理,但是测试OK package com.chinamobile.epic.http; impor ...

  5. Guiceberry+Webdriver+TestNG

    1. Guiceberry Leverage Guice to achieve Dependency Injection on your JUnit tests https://code.google ...

  6. bzoj5017: [Snoi2017]炸弹

    Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...

  7. Web jsp开发学习——新建一个项目

    然后 index.jsp编辑   新建一个servlet             准备发布      发布

  8. 使用Softmax回归将神经网络输出转成概率分布

    神经网络解决多分类问题最常用的方法是设置n个输出节点,其中n为类别的个数.对于每一个样例,神经网络可以得到一个n维数组作为输出结果.数组中的每一个维度(也就是每一个输出节点)对应一个类别,通过前向传播 ...

  9. HTML代码优化中SEO要注意哪些细节

    本文来源于学业无忧网,转载请保留:http://www.ixywy.com/ 这段时间,我们翻阅了一些同行撰写的书.其中,几乎每本书都存在问题.这个肯定在所难免,但是作为一名职业的SEO更应该注意一些 ...

  10. 在Linux里安装Samba(文件共享)方便在Windows下面操作

    第一步:安装包 在CentOS是 yum install samba 在Ubuntu是 apt install samba 第二步:添加用户 adduser 用户名 smbpasswd -a 用户名 ...