经过前面的文章,已经把行为树中的四种基本类型节点介绍了下。接下来可以整理一下,打印一下整棵行为树。注意点如下:
1.可以把BTBehaviorTree也当作一种节点,这样就可以方便地进行行为树嵌套了
2.可以在BTBehaviorTree中的SetStartTask、BTParentTask中的AddChild,即在设置节点和添加节点时对节点的信息进行打印
以下面这棵行为树为例:
BTTask.lua
1 BTTask = {}; 2 3 local this = BTTask; 4 5 function this:New() 6 local o = {}; 7 setmetatable(o, self); 8 self.__index = self; 9 o.executionStatus = BTTaskStatus.Inactive; --该节点的执行状态 10 o.root = nil; --根节点 11 o.parent = nil; --父节点 12 o.layer = 1; --第几层 13 o.index = 1; --父节点下的第几个节点 14 o.name = "BTTask"; --该节点名字 15 return o; 16 end 17 18 function this:ToString() 19 local root = "root:"; 20 if (self.root) then 21 root = root .. self.root.name; 22 else 23 root = root .. "nil"; 24 end 25 26 local parent = "parent:"; 27 if (self.parent) then 28 parent = parent .. self.parent.name; 29 else 30 parent = parent .. "nil"; 31 end 32 33 local layer = "layer:" .. self.layer; 34 local index = "index:" .. self.index; 35 local name = "name:" .. self.name; 36 37 print(root .. " " .. parent .. " " .. layer .. " " .. index .. " " .. name); 38 end
BTParentTask.lua
1 BTParentTask = BTTask:New(); 2 3 local this = BTParentTask; 4 5 function this:New() 6 local o = {}; 7 setmetatable(o, self); 8 self.__index = self; 9 o.currentChildIndex = 0; --当前运行到第几个子节点 10 o.currentChildTask = nil; --当前运行的子节点 11 o.childTasks = {}; --子节点列表 12 return o; 13 end 14 15 --添加子节点 16 function this:AddChild(task) 17 local index = #self.childTasks + 1; 18 task.index = index; 19 task.layer = self.layer + 1; 20 task.parent = self; 21 task.root = self.root; 22 self.childTasks[index] = task; 23 24 if (BTBehaviorManager.isPrintTaskInfo) then 25 print(task:ToString()); 26 end 27 end 28 29 --是否有子节点 30 function this:HasChild() 31 if (#self.childTasks > 0) then 32 return true; 33 else 34 return false; 35 end 36 end 37 38 --获取子节点数目 39 function this:GetChildCount() 40 return #self.childTasks; 41 end 42 43 --获取下一个要执行的子节点 44 function this:GetNextChild() 45 if (#self.childTasks >= (self.currentChildIndex + 1)) then 46 self.currentChildIndex = self.currentChildIndex + 1; 47 return self.childTasks[self.currentChildIndex]; 48 end 49 return nil; 50 end 51 52 --重置 53 function this:Reset() 54 self.currentChildIndex = 0; 55 self.currentChildTask = nil; 56 end
BTBehaviorTree.lua
1 --[[ 2 树的根节点 3 --]] 4 BTBehaviorTree = BTTask:New(); 5 6 local this = BTBehaviorTree; 7 8 function this:New() 9 local o = {}; 10 setmetatable(o, self); 11 self.__index = self; 12 return o; 13 end 14 15 function this:SetStartTask(task) 16 task.root = self; 17 task.parent = self; 18 task.layer = self.layer + 1; 19 self.startTask = task; 20 21 if (BTBehaviorManager.isPrintTaskInfo) then 22 print(task:ToString()); 23 end 24 end 25 26 function this:OnUpdate() 27 if (self.startTask) then 28 return self.startTask:OnUpdate(); 29 end 30 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(2); 16 local selector = BTSelector:New(); 17 local sequence = BTSequence:New(); 18 local isNullOrEmpty = BTIsNullOrEmpty:New("123"); 19 local log = BTLog:New("This is a empty string!!!"); 20 local log2 = BTLog:New("This is not a empty string"); 21 22 self:SetStartTask(repeater); 23 24 repeater:AddChild(selector); 25 26 selector:AddChild(sequence); 27 selector:AddChild(log2); 28 29 sequence:AddChild(isNullOrEmpty); 30 sequence:AddChild(log); 31 end
打印如下: