参考链接: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进行编译,结果如下: