IndieGame/client/Assets/ParadoxNotion/NodeCanvas/Modules/BehaviourTrees/BehaviourTree.cs

115 lines
4.6 KiB
C#
Raw Normal View History

2024-10-11 10:12:15 +08:00
using NodeCanvas.Framework;
using ParadoxNotion.Design;
using UnityEngine;
namespace NodeCanvas.BehaviourTrees
{
///<summary> BehaviourTrees are used to create advanced AI and logic based on simple rules.</summary>
[GraphInfo(
packageName = "NodeCanvas",
docsURL = "https://nodecanvas.paradoxnotion.com/documentation/",
resourcesURL = "https://nodecanvas.paradoxnotion.com/downloads/",
forumsURL = "https://nodecanvas.paradoxnotion.com/forums-page/"
)]
[CreateAssetMenu(menuName = "ParadoxNotion/NodeCanvas/Behaviour Tree Asset")]
public class BehaviourTree : Graph
{
///----------------------------------------------------------------------------------------------
[System.Serializable]
class DerivedSerializationData
{
public bool repeat;
public float updateInterval;
}
public override object OnDerivedDataSerialization() {
var data = new DerivedSerializationData();
data.repeat = this.repeat;
data.updateInterval = this.updateInterval;
return data;
}
public override void OnDerivedDataDeserialization(object data) {
if ( data is DerivedSerializationData ) {
this.repeat = ( (DerivedSerializationData)data ).repeat;
this.updateInterval = ( (DerivedSerializationData)data ).updateInterval;
}
}
///----------------------------------------------------------------------------------------------
///<summary>Should the tree repeat forever?</summary>
[System.NonSerialized] public bool repeat = true;
///<summary>The frequency in seconds for the tree to repeat if set to repeat.</summary>
[System.NonSerialized] public float updateInterval = 0;
///<summary>Raised when the root status of the behaviour is changed</summary>
public static event System.Action<BehaviourTree, Status> onRootStatusChanged;
private float intervalCounter;
private Status _rootStatus = Status.Resting;
///<summary>The last status of the root node</summary>
public Status rootStatus {
get { return _rootStatus; }
private set
{
if ( _rootStatus != value ) {
_rootStatus = value;
if ( onRootStatusChanged != null ) {
onRootStatusChanged(this, value);
}
}
}
}
///----------------------------------------------------------------------------------------------
public override System.Type baseNodeType => typeof(BTNode);
public override bool requiresAgent => true;
public override bool requiresPrimeNode => true;
public override bool isTree => true;
public override bool allowBlackboardOverrides => true;
sealed public override bool canAcceptVariableDrops => false;
public override ParadoxNotion.PlanarDirection flowDirection => ParadoxNotion.PlanarDirection.Vertical;
///----------------------------------------------------------------------------------------------
protected override void OnGraphStarted() {
intervalCounter = updateInterval;
rootStatus = primeNode.status;
}
protected override void OnGraphUpdate() {
if ( intervalCounter >= updateInterval ) {
intervalCounter = 0;
if ( Tick(agent, blackboard) != Status.Running && !repeat ) {
Stop(rootStatus == Status.Success);
}
}
if ( updateInterval > 0 ) {
intervalCounter += Time.deltaTime;
}
}
///<summary>Tick the tree once for the provided agent and with the provided blackboard</summary>
Status Tick(Component agent, IBlackboard blackboard) {
if ( rootStatus != Status.Running ) { primeNode.Reset(); }
return rootStatus = primeNode.Execute(agent, blackboard);
}
///----------------------------------------------------------------------------------------------
///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
[UnityEditor.MenuItem("Tools/ParadoxNotion/NodeCanvas/Create/Behaviour Tree Asset", false, 0)]
static void Editor_CreateGraph() {
var newGraph = EditorUtils.CreateAsset<BehaviourTree>();
UnityEditor.Selection.activeObject = newGraph;
}
#endif
}
}