lyh916

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  201 随笔 :: 0 文章 :: 12 评论 :: 21万 阅读

参考链接:https://blog.csdn.net/u012740992/article/details/79366251

 

在行为树中,有四种最基本的节点,其继承结构如下:

Action->Task

Conditional->Task

Decorator->ParentTask->Task

Composite->ParentTask->Task

 

对于整棵树,从上往下,可以对其进行分层,从0开始递增;对于树中的子树,从左到右,可以对其子节点标记索引。

那么,这里的整棵树,对应的就是BehaviorTree,而子树,对应的就是ParentTask。同时,为了方便节点之间的访问,可以引入root和parent,表示该节点的根节点和父节点。

然后我们可以通过BehaviorManager去管理所有的树。

整体结构如下:

 

 

代码如下:

Task.lua

复制代码
 1 BTree.Task = {};
 2 
 3 local this = BTree.Task;
 4 
 5 function this:New(o)
 6     o = o or {};
 7     setmetatable(o, self);
 8     self.__index = self;
 9     return o;
10 end
复制代码

 

ParentTask.lua

复制代码
 1 BTree.ParentTask = BTree.Task:New();
 2 
 3 local this = BTree.ParentTask;
 4 
 5 function this:New(o)
 6     o = o or {};
 7     o.curChilIndex = 0;--当前运行到第几个子节点
 8     o.childTasks = {};--子节点列表
 9     setmetatable(o, self);
10     self.__index = self;
11     return o;
12 end
13 
14 function this:AddChild(task)
15     local index = #self.childTasks + 1;
16     task.index = index;
17     task.layer = self.layer + 1;
18     task.parent = self;
19     task.root = self.root;
20 end
复制代码

 

BehaviorTree.lua

复制代码
 1 --[[
 2 树的根节点
 3 --]]
 4 BTree.BehaviorTree = {
 5     layer = 0,
 6 };
 7 
 8 local this = BTree.BehaviorTree;
 9 
10 function this:New(o)
11     o = o or {};
12     setmetatable(o, self);
13     self.__index = self;
14     return o;
15 end
16 
17 function this:PushTask(task)
18     task.root = self;
19     task.parent = self;
20     task.layer = self.layer + 1;
21     self.startTask = task;
22 end
23 
24 function this:OnUpdate()
25     if (self.startTask) then
26         return self.startTask:OnUpdate();
27     end
28 end
复制代码

 

BehaviorManager.lua

复制代码
 1 BTree.BehaviorManager = {};
 2 
 3 local this = BTree.BehaviorManager;
 4 
 5 function this.RunTree(tree)
 6     this.bTree = tree;
 7     this.OnUpdate();
 8 end
 9 
10 function this.OnUpdate()
11     local status = this.bTree:OnUpdate();
12     while (status == BTree.TaskStatus.Running) do
13         status = this.bTree:OnUpdate();
14     end
15 end
复制代码

 

这里可以使用一棵简单的行为树来进行测试:

Log.lua

复制代码
 1 --[[
 2 参考BehaviorDesigner-Action-Log
 3 --]]
 4 BTree.Log = BTree.Action:New();
 5 
 6 local this = BTree.Log;
 7 
 8 function this:New(text)
 9     local o = {};
10     setmetatable(o, self);
11     self.__index = self;
12     self.text = text;
13     return o;
14 end
15 
16 function this:OnUpdate()
17     print(self.text);
18     return BTree.TaskStatus.Success;
19 end
复制代码

 

TestBehaviorTree.lua

复制代码
 1 TestBehaviorTree = BTree.BehaviorTree:New();
 2 
 3 local this = TestBehaviorTree;
 4 
 5 function this:New(o)
 6     o = o or {};
 7     setmetatable(o, self);
 8     self.__index = self;
 9     this:Init();
10     return o;
11 end
12 
13 function this:Init()
14     local log = BTree.Log:New("hello world!");
15     this:PushTask(log);
16 end
复制代码

 

TestMain.lua

1 require "BehaviorTree/Core/Init"
2 require "BehaviorTree/Test/TestBehaviorTree"
3 
4 local tree = TestBehaviorTree:New();
5 BTree.BehaviorManager.RunTree(tree);

 

运行环境:Sublime Text 3,使用while循环来代替每帧执行,按F7进行编译,结果如下:

posted on   艰苦奋斗中  阅读(1520)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示