
1.引入URP 2.引入InputSystem 3.引入Fungus 4.引入DoTween 5.引入CinemaMachine 6.引入BehaviorTree 7.引入BehaviorTree动作包 8.配置了渲染管线资源 🥵🥵🥵🥵🥵
102 lines
4.1 KiB
C#
102 lines
4.1 KiB
C#
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.")]
|
|
[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<int> childIndexList = new List<int>();
|
|
// The random child index execution order.
|
|
private Stack<int> childrenExecutionOrder = new Stack<int>();
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
} |