zoukankan      html  css  js  c++  java
  • [Unity插件]Lua行为树(十一):组合节点Parallel

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

    例如说,给Sequence节点插入一个不断返回Running的行为节点,那么就会造成后面的子节点无法执行,而对于Parallel来说,是不会存在这种阻塞情况的。

    Parallel.cs

     1 namespace BehaviorDesigner.Runtime.Tasks
     2 {
     3     [TaskDescription("Similar to the sequence task, the parallel task will run each child task until a child task returns failure. " +
     4                      "The difference is that the parallel task will run all of its children tasks simultaneously versus running each task one at a time. " +
     5                      "Like the sequence class, the parallel task will return success once all of its children tasks have return success. " +
     6                      "If one tasks returns failure the parallel task will end all of the child tasks and return failure.")]
     7     [HelpURL("http://www.opsive.com/assets/BehaviorDesigner/documentation.php?id=27")]
     8     [TaskIcon("{SkinColor}ParallelIcon.png")]
     9     public class Parallel : Composite
    10     {
    11         // The index of the child that is currently running or is about to run.
    12         private int currentChildIndex;
    13         // The task status of every child task.
    14         private TaskStatus[] executionStatus;
    15 
    16         public override void OnAwake()
    17         {
    18             // Create a new task status array that will hold the execution status of all of the children tasks.
    19             executionStatus = new TaskStatus[children.Count];
    20         }
    21 
    22         public override void OnChildStarted(int childIndex)
    23         {
    24             // One of the children has started to run. Increment the child index and set the current task status of that child to running.
    25             currentChildIndex++;
    26             executionStatus[childIndex] = TaskStatus.Running;
    27         }
    28 
    29         public override bool CanRunParallelChildren()
    30         {
    31             // This task can run parallel children.
    32             return true;
    33         }
    34 
    35         public override int CurrentChildIndex()
    36         {
    37             return currentChildIndex;
    38         }
    39 
    40         public override bool CanExecute()
    41         {
    42             // We can continue executing if we have more children that haven't been started yet.
    43             return currentChildIndex < children.Count;
    44         }
    45 
    46         public override void OnChildExecuted(int childIndex, TaskStatus childStatus)
    47         {
    48             // One of the children has finished running. Set the task status.
    49             executionStatus[childIndex] = childStatus;
    50         }
    51 
    52         public override TaskStatus OverrideStatus(TaskStatus status)
    53         {
    54             // Assume all of the children have finished executing. Loop through the execution status of every child and check to see if any tasks are currently running
    55             // or failed. If a task is still running then all of the children are not done executing and the parallel task should continue to return a task status of running.
    56             // If a task failed then return failure. The Behavior Manager will stop all of the children tasks. If no child task is running or has failed then the parallel
    57             // task succeeded and it will return success.
    58             bool childrenComplete = true;
    59             for (int i = 0; i < executionStatus.Length; ++i) {
    60                 if (executionStatus[i] == TaskStatus.Running) {
    61                     childrenComplete = false;
    62                 } else if (executionStatus[i] == TaskStatus.Failure) {
    63                     return TaskStatus.Failure;
    64                 }
    65             }
    66             return (childrenComplete ? TaskStatus.Success : TaskStatus.Running);
    67         }
    68 
    69         public override void OnConditionalAbort(int childIndex)
    70         {
    71             // Start from the beginning on an abort
    72             currentChildIndex = 0;
    73             for (int i = 0; i < executionStatus.Length; ++i) {
    74                 executionStatus[i] = TaskStatus.Inactive;
    75             }
    76         }
    77 
    78         public override void OnEnd()
    79         {
    80             // Reset the execution status and the child index back to their starting values.
    81             for (int i = 0; i < executionStatus.Length; ++i) {
    82                 executionStatus[i] = TaskStatus.Inactive;
    83             }
    84             currentChildIndex = 0;
    85         }
    86     }
    87 }

    BTParallel.lua

     1 BTParallel = BTComposite:New();
     2 
     3 local this = BTParallel;
     4 this.name = "BTParallel";
     5 
     6 function this:New()
     7     local o = {};
     8     setmetatable(o, self);
     9     self.__index = self;
    10     o.childTasks = {};
    11     o.executionStatus = {};
    12     return o;
    13 end
    14 
    15 function this:OnUpdate()
    16     if (not self:HasChild()) then
    17         return BTTaskStatus.Failure;
    18     end
    19 
    20     for i=1,#self.childTasks do
    21         local childTask = self.childTasks[i];
    22         if (not self.executionStatus[i]) then --第一次执行
    23             self.executionStatus[i] = childTask:OnUpdate();
    24             if (self.executionStatus[i] == BTTaskStatus.Failure) then
    25                 return BTTaskStatus.Failure;
    26             end
    27         elseif (self.executionStatus[i] == BTTaskStatus.Running) then --第二次以及以后执行
    28             self.executionStatus[i] = childTask:OnUpdate();
    29             if (self.executionStatus[i] == BTTaskStatus.Failure) then
    30                 return BTTaskStatus.Failure;
    31             end
    32         end
    33     end
    34 
    35     local childrenComplete = true;
    36     for i=1,#self.executionStatus do
    37         if (self.executionStatus[i] == BTTaskStatus.Running) then
    38             childrenComplete = false;
    39             break;
    40         end
    41     end
    42     if (childrenComplete) then
    43         return BTTaskStatus.Success;
    44     else
    45         return BTTaskStatus.Running;
    46     end
    47 end

    测试如下:

    1.BTSequence和BTParallel的对比

     BTSequence:

     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     o:Init();
    11     return o;
    12 end
    13 
    14 function this:Init()
    15     local sequence = BTSequence:New();
    16     local action = self:GetBTActionUniversal();
    17     local log = BTLog:New("This is log!!!");
    18     log.name = "log";
    19 
    20     self:SetStartTask(sequence);
    21 
    22     sequence:AddChild(action);
    23     sequence:AddChild(log);
    24 end
    25 
    26 function this:GetBTActionUniversal()
    27     local count = 1;
    28     local a = function ()
    29         if (count <= 3) then
    30             count = count + 1;
    31             print("22");
    32             return BTTaskStatus.Running;
    33         else
    34             return BTTaskStatus.Success;
    35         end
    36     end
    37     local universal = BTActionUniversal:New(nil, a);
    38     return universal;
    39 end

    BTParallel:

     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     o:Init();
    11     return o;
    12 end
    13 
    14 function this:Init()
    15     local parallel = BTParallel:New();
    16     local action = self:GetBTActionUniversal();
    17     local log = BTLog:New("This is log!!!");
    18     log.name = "log";
    19 
    20     self:SetStartTask(parallel);
    21 
    22     parallel:AddChild(action);
    23     parallel:AddChild(log);
    24 end
    25 
    26 function this:GetBTActionUniversal()
    27     local count = 1;
    28     local a = function ()
    29         if (count <= 3) then
    30             count = count + 1;
    31             print("22");
    32             return BTTaskStatus.Running;
    33         else
    34             return BTTaskStatus.Success;
    35         end
    36     end
    37     local universal = BTActionUniversal:New(nil, a);
    38     return universal;
    39 end

    2.BTParallel中返回失败中断执行的情况

     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     o:Init();
    11     return o;
    12 end
    13 
    14 function this:Init()
    15     local parallel = BTParallel:New();
    16     local action = self:GetBTActionUniversal();
    17     local action2 = self:GetBTActionUniversal2();
    18 
    19     self:SetStartTask(parallel);
    20 
    21     parallel:AddChild(action);
    22     parallel:AddChild(action2);
    23 end
    24 
    25 function this:GetBTActionUniversal()
    26     local count = 1;
    27     local a = function ()
    28         if (count <= 3) then
    29             count = count + 1;
    30             print("22");
    31             return BTTaskStatus.Running;
    32         else
    33             return BTTaskStatus.Success;
    34         end
    35     end
    36     local universal = BTActionUniversal:New(nil, a);
    37     return universal;
    38 end
    39 
    40 function this:GetBTActionUniversal2()
    41     local universal = BTActionUniversal:New(nil, function ()
    42         return BTTaskStatus.Failure;
    43     end);
    44     return universal;
    45 end

  • 相关阅读:
    【模板】扩展中国剩余定理(EXCRT)
    战略游戏(树形DP)
    二叉苹果树(树形DP)
    货车运输(最大生成树,LCA)
    [CQOI2016]密钥破解
    Pollard-Rho算法andMiller_Rabin算法
    [TJOI2009]猜数字(中国剩余定理)
    中国剩余定理(学习笔记)
    线段树 Segment Tree
    辗转相除法
  • 原文地址:https://www.cnblogs.com/lyh916/p/9665782.html
Copyright © 2011-2022 走看看