From 6ee18886c8af3858de5e97599b23086823d9f320 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 27 Jan 2021 16:30:19 +0800 Subject: =?UTF-8?q?*=E6=9B=B4=E6=96=B0Behaviour=20Designer=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E5=9C=A8=E6=9C=80=E4=B8=8B=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=9C=89BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Composites/Parallel.cs.meta | 15 +-- .../Runtime/Composites/ParallelSelector.cs.meta | 15 +-- .../Runtime/Composites/PrioritySelector.cs.meta | 15 +-- .../Runtime/Composites/RandomSelector.cs | 4 + .../Runtime/Composites/RandomSelector.cs.meta | 15 +-- .../Runtime/Composites/RandomSequence.cs | 4 + .../Runtime/Composites/RandomSequence.cs.meta | 15 +-- .../Runtime/Composites/Selector.cs.meta | 15 +-- .../Runtime/Composites/SelectorEvaluator.cs | 4 +- .../Runtime/Composites/SelectorEvaluator.cs.meta | 16 +-- .../Runtime/Composites/Sequence.cs.meta | 15 +-- .../Runtime/Composites/UtilitySelector.cs | 150 +++++++++++++++++++++ .../Runtime/Composites/UtilitySelector.cs.meta | 12 ++ 13 files changed, 228 insertions(+), 67 deletions(-) create mode 100644 Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs create mode 100644 Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs.meta (limited to 'Client/Assets/Behavior Designer/Runtime/Composites') diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/Parallel.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/Parallel.cs.meta index 83e99844..42400c12 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/Parallel.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/Parallel.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 4a7063721a0dbc04787bec1b0507f9ae -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 4a7063721a0dbc04787bec1b0507f9ae +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/ParallelSelector.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/ParallelSelector.cs.meta index 37b9893c..5b8aa3c2 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/ParallelSelector.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/ParallelSelector.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 52e4e27ad95cedb41a3bc2c5f5ed0b54 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 52e4e27ad95cedb41a3bc2c5f5ed0b54 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/PrioritySelector.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/PrioritySelector.cs.meta index fd866f4e..a532df05 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/PrioritySelector.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/PrioritySelector.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 8b5aa86ad86e94f41841abd04bd96f2a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 8b5aa86ad86e94f41841abd04bd96f2a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs index ed625e1f..e2cb5b10 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs +++ b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs @@ -28,7 +28,11 @@ namespace BehaviorDesigner.Runtime.Tasks { // If specified, use the seed provided. if (useSeed) { +#if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3) Random.InitState(seed); +#else + Random.seed = seed; +#endif } // Add the index of each child to a list to make the Fischer-Yates shuffle possible. diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs.meta index 1f33af10..cb56d7b7 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSelector.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 4952cbfc1e77be24b99e34c9acffc2a0 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 4952cbfc1e77be24b99e34c9acffc2a0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs index 0d4e2223..14a6e646 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs +++ b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs @@ -29,7 +29,11 @@ namespace BehaviorDesigner.Runtime.Tasks { // If specified, use the seed provided. if (useSeed) { +#if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3) Random.InitState(seed); +#else + Random.seed = seed; +#endif } // Add the index of each child to a list to make the Fischer-Yates shuffle possible. diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs.meta index 0f3ca379..01b06990 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/RandomSequence.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 11b102c97eb687b4a9ce1473a334c3dd -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 11b102c97eb687b4a9ce1473a334c3dd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/Selector.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/Selector.cs.meta index 3552ecf6..9142a26d 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/Selector.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/Selector.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: 7cb8dcec14880a443841212e6b595d4f -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 7cb8dcec14880a443841212e6b595d4f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs b/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs index 08bd350c..25505d63 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs +++ b/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs @@ -1,6 +1,4 @@ -using UnityEngine; - -namespace BehaviorDesigner.Runtime.Tasks +namespace BehaviorDesigner.Runtime.Tasks { [TaskDescription("The selector evaluator is a selector task which reevaluates its children every tick. It will run the lowest priority child which returns a task status of running. " + "This is done each tick. If a higher priority child is running and the next frame a lower priority child wants to run it will interrupt the higher priority child. " + diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs.meta index b55971ba..56bbd94d 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/SelectorEvaluator.cs.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 15b5d0aafd7d4f04f8332d33705ebd63 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: 15b5d0aafd7d4f04f8332d33705ebd63 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/Sequence.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/Sequence.cs.meta index 068578b3..eea9bec1 100644 --- a/Client/Assets/Behavior Designer/Runtime/Composites/Sequence.cs.meta +++ b/Client/Assets/Behavior Designer/Runtime/Composites/Sequence.cs.meta @@ -1,8 +1,7 @@ -fileFormatVersion: 2 -guid: b7226608b64066c40a656d7260249fce -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: +fileFormatVersion: 2 +guid: b7226608b64066c40a656d7260249fce +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs b/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs new file mode 100644 index 00000000..23fd6a54 --- /dev/null +++ b/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs @@ -0,0 +1,150 @@ +using System.Collections.Generic; + +namespace BehaviorDesigner.Runtime.Tasks +{ + [TaskDescription("The utility selector task evaluates the child tasks using Utility Theory AI. The child task can override the GetUtility method and return the utility value " + + "at that particular time. The task with the highest utility value will be selected and the existing running task will be aborted. The utility selector " + + "task reevaluates its children every tick.")] + [HelpURL("http://www.opsive.com/assets/BehaviorDesigner/documentation.php?id=134")] + [TaskIcon("{SkinColor}UtilitySelectorIcon.png")] + public class UtilitySelector : Composite + { + // The index of the child that is currently running or is about to run. + private int currentChildIndex = 0; + // The highest utility value + private float highestUtility; + // The task status of the last child ran. + private TaskStatus executionStatus = TaskStatus.Inactive; + // Is the task being reevaluated? + private bool reevaluating; + // A list of children that can execute. + private List availableChildren = new List(); + + public override void OnStart() + { + highestUtility = float.MinValue; + + // Loop through each child task and determine its utility. The task with the highest utility will run first. + availableChildren.Clear(); + for (int i = 0; i < children.Count; ++i) { + float utility = children[i].GetUtility(); + if (utility > highestUtility) { + highestUtility = utility; + currentChildIndex = i; + } + availableChildren.Add(i); + } + } + + public override int CurrentChildIndex() + { + // The currentChildIndex is the task with the highest utility. + return currentChildIndex; + } + + public override void OnChildStarted(int childIndex) + { + // The child has started - set the execution status. + executionStatus = TaskStatus.Running; + } + + public override bool CanExecute() + { + // Continue to execute new tasks until a task returns success or there are no more children left. If reevaluating then return false + // immediately because each task doesn't need to be reevaluted. + if (executionStatus == TaskStatus.Success || executionStatus == TaskStatus.Running || reevaluating) { + return false; + } + return availableChildren.Count > 0; + } + + public override void OnChildExecuted(int childIndex, TaskStatus childStatus) + { + // The child status will be inactive immediately following an abort from OnReevaluationEnded. The status will be running if the + // child task is interrupted. Ignore the status for both of these. + if (childStatus != TaskStatus.Inactive && childStatus != TaskStatus.Running) { + executionStatus = childStatus; + // If the execution status is failure then a new task needs to be selected. Remove the current task from the available children + // and select the next highest utility child. + if (executionStatus == TaskStatus.Failure) { + availableChildren.Remove(childIndex); + + highestUtility = float.MinValue; + for (int i = 0; i < availableChildren.Count; ++i) { + float utility = children[availableChildren[i]].GetUtility(); + if (utility > highestUtility) { + highestUtility = utility; + currentChildIndex = availableChildren[i]; + } + } + } + } + } + + public override void OnConditionalAbort(int childIndex) + { + // Set the current child index to the index that caused the abort + currentChildIndex = childIndex; + executionStatus = TaskStatus.Inactive; + } + + public override void OnEnd() + { + // All of the children have run. Reset the variables back to their starting values. + executionStatus = TaskStatus.Inactive; + currentChildIndex = 0; + } + + public override TaskStatus OverrideStatus(TaskStatus status) + { + return executionStatus; + } + + // The utility selector task is a parallel task to allow the task utility to be reevaluated. The higest utility task will always run. + public override bool CanRunParallelChildren() + { + return true; + } + + // Can reevaluate to allow the task utilities to be rerun. + public override bool CanReevaluate() + { + return true; + } + + // The behavior tree wants to start reevaluating the tree. + public override bool OnReevaluationStarted() + { + // Cannot reevaluate if the task hasn't even started yet + if (executionStatus == TaskStatus.Inactive) { + return false; + } + + reevaluating = true; + return true; + } + + // Determine if a task with a higher utility exists. + public override void OnReevaluationEnded(TaskStatus status) + { + reevaluating = false; + + // Loop through all of the available children and pick the task with the highest utility. + int prevChildIndex = currentChildIndex; + highestUtility = float.MinValue; + for (int i = 0; i < availableChildren.Count; ++i) { + float utility = children[availableChildren[i]].GetUtility(); + if (utility > highestUtility) { + highestUtility = utility; + currentChildIndex = availableChildren[i]; + } + } + + // If the index is different then the current child task should be aborted and the higher utility task should be run. + if (prevChildIndex != currentChildIndex) { + BehaviorManager.instance.Interrupt(Owner, children[prevChildIndex], this); + executionStatus = TaskStatus.Inactive; + } + } + } +} \ No newline at end of file diff --git a/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs.meta b/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs.meta new file mode 100644 index 00000000..f65ef498 --- /dev/null +++ b/Client/Assets/Behavior Designer/Runtime/Composites/UtilitySelector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1c21b01ca0aa9004fa3a76c9d596eeb1 +timeCreated: 1465679373 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: -- cgit v1.1-26-g67d0