using NodeCanvas.Framework; using ParadoxNotion; using ParadoxNotion.Design; using UnityEngine; namespace NodeCanvas.BehaviourTrees { [Name("Sequencer", 10)] [Category("Composites")] [Description("Executes its children in order and returns Success if all children return Success. As soon as a child returns Failure, the Sequencer will stop and return Failure as well.")] [ParadoxNotion.Design.Icon("Sequencer")] [Color("bf7fff")] public class Sequencer : BTComposite { [Tooltip("If true, then higher priority children are re-evaluated per frame and if either returns Failure, then the Sequencer will immediately stop and return Failure as well.")] public bool dynamic; [Tooltip("If true, the children order of execution is shuffled each time the Sequencer resets.")] public bool random; private int lastRunningNodeIndex = 0; protected override Status OnExecute(Component agent, IBlackboard blackboard) { for ( var i = dynamic ? 0 : lastRunningNodeIndex; i < outConnections.Count; i++ ) { status = outConnections[i].Execute(agent, blackboard); switch ( status ) { case Status.Running: if ( dynamic && i < lastRunningNodeIndex ) { for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) { outConnections[j].Reset(); } } lastRunningNodeIndex = i; return Status.Running; case Status.Failure: if ( dynamic && i < lastRunningNodeIndex ) { for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) { outConnections[j].Reset(); } } return Status.Failure; } } return Status.Success; } protected override void OnReset() { lastRunningNodeIndex = 0; if ( random ) { outConnections = outConnections.Shuffle(); } } public override void OnChildDisconnected(int index) { if ( index != 0 && index == lastRunningNodeIndex ) { lastRunningNodeIndex--; } } public override void OnGraphStarted() { OnReset(); } ///---------------------------------------------------------------------------------------------- ///---------------------------------------UNITY EDITOR------------------------------------------- #if UNITY_EDITOR protected override void OnNodeGUI() { if ( dynamic ) { GUILayout.Label("DYNAMIC"); } if ( random ) { GUILayout.Label("RANDOM"); } } #endif } }