之前介绍了组合节点中三大常用的节点:BTSequence、BTSelector和BTParallel,一般来说,这三种就够用了,可以满足很多的需求。
接下来可以完善一下装饰节点,增加几种新的节点。
1.BTInverter
1 --[[ 2 结果取反: 3 1.子节点返回Running,则节点返回Running 4 2.子节点返回Success,则节点返回Failure 5 3.子节点返回Failure,则节点返回Success 6 --]] 7 BTInverter = BTDecorator:New(); 8 9 local this = BTInverter; 10 this.name = "BTInverter"; 11 12 function this:New() 13 local o = {}; 14 setmetatable(o, self); 15 self.__index = self; 16 o.childTasks = {}; 17 return o; 18 end 19 20 function this:OnUpdate() 21 if (not self.currentChildTask) then 22 self.currentChildTask = self:GetChild(); 23 if (not self.currentChildTask) then 24 return BTTaskStatus.Failure; 25 end 26 end 27 28 self.executionStatus = self.currentChildTask:OnUpdate(); 29 30 if (self.executionStatus == BTTaskStatus.Running) then 31 return BTTaskStatus.Running; 32 elseif (self.executionStatus == BTTaskStatus.Success) then 33 return BTTaskStatus.Failure; 34 else 35 return BTTaskStatus.Success; 36 end 37 end 38 39 function this:Reset() 40 self.executionStatus = BTTaskStatus.Inactive; 41 BTParentTask.Reset(self); 42 end
测试:
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 o:Init(); 11 return o; 12 end 13 14 function this:Init() 15 local sequence = BTSequence:New(); 16 local inverter = BTInverter:New(); 17 local isNullOrEmpty = BTIsNullOrEmpty:New("123"); 18 local log = BTLog:New("This is a tree!!!"); 19 20 self:SetStartTask(sequence); 21 22 inverter:AddChild(isNullOrEmpty); 23 24 sequence:AddChild(inverter); 25 sequence:AddChild(log); 26 end
输出:
2.BTReturnFailure
1 --[[ 2 结果返回失败: 3 1.子节点返回Running,则节点返回Running 4 2.其余情况,则节点返回Failure 5 --]] 6 BTReturnFailure = BTDecorator:New(); 7 8 local this = BTReturnFailure; 9 this.name = "BTReturnFailure"; 10 11 function this:New() 12 local o = {}; 13 setmetatable(o, self); 14 self.__index = self; 15 o.childTasks = {}; 16 return o; 17 end 18 19 function this:OnUpdate() 20 if (not self.currentChildTask) then 21 self.currentChildTask = self:GetChild(); 22 if (not self.currentChildTask) then 23 return BTTaskStatus.Failure; 24 end 25 end 26 27 self.executionStatus = self.currentChildTask:OnUpdate(); 28 29 if (self.executionStatus == BTTaskStatus.Running) then 30 return BTTaskStatus.Running; 31 else 32 return BTTaskStatus.Failure; 33 end 34 end 35 36 function this:Reset() 37 self.executionStatus = BTTaskStatus.Inactive; 38 BTParentTask.Reset(self); 39 end
测试:
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 o:Init(); 11 return o; 12 end 13 14 function this:Init() 15 local selector = BTSelector:New(); 16 local returnFailure = BTReturnFailure:New(); 17 local isNullOrEmpty = BTIsNullOrEmpty:New(); 18 local log = BTLog:New("This is a tree!!!"); 19 20 self:SetStartTask(selector); 21 22 returnFailure:AddChild(isNullOrEmpty); 23 24 selector:AddChild(returnFailure); 25 selector:AddChild(log); 26 end
输出:
3.BTUntilFailure
1 --[[ 2 结果返回失败: 3 1.子节点返回Failure,则节点返回Failure 4 2.其余情况,则节点返回Running 5 --]] 6 BTUntilFailure = BTDecorator:New(); 7 8 local this = BTUntilFailure; 9 this.name = "BTUntilFailure"; 10 11 function this:New() 12 local o = {}; 13 setmetatable(o, self); 14 self.__index = self; 15 o.childTasks = {}; 16 return o; 17 end 18 19 function this:OnUpdate() 20 if (not self.currentChildTask) then 21 self.currentChildTask = self:GetChild(); 22 if (not self.currentChildTask) then 23 return BTTaskStatus.Failure; 24 end 25 end 26 27 self.executionStatus = self.currentChildTask:OnUpdate(); 28 29 if (self.executionStatus ~= BTTaskStatus.Failure) then 30 return BTTaskStatus.Running; 31 else 32 return BTTaskStatus.Failure; 33 end 34 end 35 36 function this:Reset() 37 self.executionStatus = BTTaskStatus.Inactive; 38 BTParentTask.Reset(self); 39 end
测试:
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 o:Init(); 11 return o; 12 end 13 14 function this:Init() 15 local selector = BTSelector:New(); 16 local untilFailure = BTUntilFailure:New(); 17 local action = self:GetBTActionUniversal(); 18 local log = BTLog:New("This is a tree!!!"); 19 20 self:SetStartTask(selector); 21 22 untilFailure:AddChild(action); 23 24 selector:AddChild(untilFailure); 25 selector:AddChild(log); 26 end 27 28 function this:GetBTActionUniversal() 29 local count = 1; 30 local a = function () 31 if (count == 1) then 32 count = count + 1; 33 print("11"); 34 return BTTaskStatus.Success; 35 elseif (count == 2) then 36 count = count + 1; 37 print("22"); 38 return BTTaskStatus.Running; 39 else 40 print("33"); 41 return BTTaskStatus.Failure; 42 end 43 end 44 local universal = BTActionUniversal:New(nil, a); 45 return universal; 46 end
输出:
最后给出这个系列的源码:
https://pan.baidu.com/s/1QwjozJ3dEpqNRL04oLvfHw