private TaskStatus RunTask(BehaviorManager.BehaviorTree behaviorTree, int taskIndex, int stackIndex) { Task task = behaviorTree.taskList[taskIndex]; // 第一步:加保护 if (null == task) { Debug.LogError("NULL TASK"); return(TaskStatus.Failure); } TaskStatus taskStatus = task.NodeData.ExecutionStatus; // 第二步:Push,再在Push里调用OnStart PushTask(behaviorTree, taskIndex, stackIndex); // 第三步:如果是父节点 if (task is ParentTask) { ParentTask parentTask = task as ParentTask; int childIndex = -1; TaskStatus currentChildTaskStatus = TaskStatus.Inactive; // 1、父节点是否已经执行完所有孩子了 while (parentTask.CanExecute()) { if (task is Decorator && (behaviorTree.decoratorIndexList.Contains(taskIndex))) { break; } // 2、如果可以并行地执行所有孩子就不用等当前孩子跑完 if (parentTask.CanRunParallelChildren() || TaskStatus.Running != currentChildTaskStatus) { childIndex = parentTask.CurrentChildIndex(); int nextRunTaskIndex = behaviorTree.GetIndexInTaskList(taskIndex, childIndex); if (parentTask.CanRunParallelChildren()) { behaviorTree.activeStackList.Add(new Stack <int>()); stackIndex = behaviorTree.activeStackList.Count - 1; parentTask.OnChildStarted(childIndex); } else { parentTask.OnChildStarted(); } // 3、跑下一个子节点 currentChildTaskStatus = RunTask(behaviorTree, nextRunTaskIndex, stackIndex); taskStatus = currentChildTaskStatus; if (parentTask is Decorator) { behaviorTree.decoratorIndexList.Add(taskIndex); behaviorTree.decoratorIndexStatusDic.Add(taskIndex, parentTask.OverrideStatus(taskStatus)); } } else { break; } } // 关于Decorator的特殊逻辑 if (task is Decorator && behaviorTree.decoratorIndexList.Contains(taskIndex)) { taskStatus = behaviorTree.decoratorIndexStatusDic[taskIndex]; behaviorTree.decoratorIndexList.Remove(taskIndex); behaviorTree.decoratorIndexStatusDic.Remove(taskIndex); return(taskStatus); } taskStatus = parentTask.OverrideStatus(taskStatus); } // 第四步:如果是子节点,直接跑自己的OnUpdate else { taskStatus = task.OnUpdate(); } // 保存好本帧自己的执行结果 task.NodeData.ExecutionStatus = taskStatus; // 第五步:不管是正常跑完还是非正常终止的都要调下OnEnd if (TaskStatus.Running != taskStatus) { PopTask(behaviorTree, taskIndex, stackIndex, (task is ParentTask)); } return(taskStatus); }