From 97da432c35b8c7aaf9dd2c39e2aa4b1f55f36065 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 27 Jan 2021 16:15:06 +0800 Subject: +behaviour designer --- .../Runtime/Composites/RandomSequence.cs | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs (limited to 'Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs') diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs new file mode 100644 index 00000000..0d4e2223 --- /dev/null +++ b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs @@ -0,0 +1,103 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace BehaviorDesigner.Runtime.Tasks +{ + [TaskDescription("Similar to the sequence task, the random sequence task will return success as soon as every child task returns success. " + + "The difference is that the random sequence class will run its children in a random order. The sequence task is deterministic " + + "in that it will always run the tasks from left to right within the tree. The random sequence task shuffles the child tasks up and then begins " + + "execution in a random order. Other than that the random sequence class is the same as the sequence class. It will stop running tasks " + + "as soon as a single task ends in failure. On a task failure it will stop executing all of the child tasks and return failure. " + + "If no child returns failure then it will return success.")] + [HelpURL("http://www.opsive.com/assets/BehaviorDesigner/documentation.php?id=31")] + [TaskIcon("{SkinColor}RandomSequenceIcon.png")] + public class RandomSequence : Composite + { + [Tooltip("Seed the random number generator to make things easier to debug")] + public int seed = 0; + [Tooltip("Do we want to use the seed?")] + public bool useSeed = false; + + // A list of indexes of every child task. This list is used by the Fischer-Yates shuffle algorithm. + private List childIndexList = new List(); + // The random child index execution order. + private Stack childrenExecutionOrder = new Stack(); + // The task status of the last child ran. + private TaskStatus executionStatus = TaskStatus.Inactive; + + public override void OnAwake() + { + // If specified, use the seed provided. + if (useSeed) { + Random.InitState(seed); + } + + // Add the index of each child to a list to make the Fischer-Yates shuffle possible. + childIndexList.Clear(); + for (int i = 0; i < children.Count; ++i) { + childIndexList.Add(i); + } + } + + public override void OnStart() + { + // Randomize the indecies + ShuffleChilden(); + } + + public override int CurrentChildIndex() + { + // Peek will return the index at the top of the stack. + return childrenExecutionOrder.Peek(); + } + + public override bool CanExecute() + { + // Continue exectuion if no task has return failure and indexes still exist on the stack. + return childrenExecutionOrder.Count > 0 && executionStatus != TaskStatus.Failure; + } + + public override void OnChildExecuted(TaskStatus childStatus) + { + // Pop the top index from the stack and set the execution status. + if (childrenExecutionOrder.Count > 0) { + childrenExecutionOrder.Pop(); + } + executionStatus = childStatus; + } + + public override void OnConditionalAbort(int childIndex) + { + // Start from the beginning on an abort + childrenExecutionOrder.Clear(); + executionStatus = TaskStatus.Inactive; + ShuffleChilden(); + } + + public override void OnEnd() + { + // All of the children have run. Reset the variables back to their starting values. + executionStatus = TaskStatus.Inactive; + childrenExecutionOrder.Clear(); + } + + public override void OnReset() + { + // Reset the public properties back to their original values + seed = 0; + useSeed = false; + } + + private void ShuffleChilden() + { + // Use Fischer-Yates shuffle to randomize the child index order. + for (int i = childIndexList.Count; i > 0; --i) { + int j = Random.Range(0, i); + int index = childIndexList[j]; + childrenExecutionOrder.Push(index); + childIndexList[j] = childIndexList[i - 1]; + childIndexList[i - 1] = index; + } + } + } +} \ No newline at end of file -- cgit v1.1-26-g67d0