UP-Viagg-io/Viagg-io/Assets/Packages/MyBT/BT/Node/TreeNode.cs

86 lines
4.3 KiB
C#
Raw Normal View History

2024-01-19 16:30:05 +01:00
//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
//
// Purpose: Part of the My Behaviour Tree Code
//
//=============================================================================
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using UnityEngine;
namespace MyBT {
[XmlInclude(typeof(DecoratorNode))]
public class TreeNode : Node {
// the "parent" run tree node, must be null in root treenode
[SerializeField]
public string treeNodeName;
public void Init(int _nodeDepth, Token[] _tokens, string _name) {
base.Init(_nodeDepth, _tokens);
treeNodeName = _name;
}
public override IEnumerable<NodeResult> Tick(NodeRuntimeData parentNodeRuntimeData, int recursions) {
if (debugInternalActive) {
Debug.Log(NodeLogger($"Tick", $""));
}
// only work with 1 child && failsave in case we have an infinite loop
if ((children.Count == 1) && (recursions < recursionLimit)) {
using (NodeRuntimeData myNodeRuntimeData = new NodeRuntimeData(this, parentNodeRuntimeData)) {
myNodeRuntimeData.tickExecuteEnumerator = children[0].Tick(myNodeRuntimeData, recursions + 1).GetEnumerator();
myNodeRuntimeData.taskHasChanges = base.PreTick(NodeExecute.Run, myNodeRuntimeData);
// the second check of myNodeRuntimeData.tickExecuteEnumerator is intended, as movenext may destroy it
while ((myNodeRuntimeData.tickExecuteEnumerator != null) && myNodeRuntimeData.tickExecuteEnumerator.MoveNext()) {
// if (myNodeRuntimeData == null) {
// Debug.LogError(NodeLogger("RunTreeNode.Tick", $"myNodeRuntimeData is null"));
// }
if (myNodeRuntimeData.tickExecuteEnumerator == null) {
Debug.LogError(NodeLogger("RunTreeNode.Tick", $"myNodeRuntimeData.tickExecuteEnumerator is null, movenext destroyed it"));
break;
}
myNodeRuntimeData.nodeResult = myNodeRuntimeData.tickExecuteEnumerator.Current;
if (debugInternalActive) Debug.Log(NodeLogger($"Tick.before", $"nodeResult {myNodeRuntimeData.nodeResult}"));
// return the same result as the child
myNodeRuntimeData.taskHasChanges |= base.PostTick(NodeExecute.Run, myNodeRuntimeData);
if (myNodeRuntimeData.taskHasChanges && taskController) {
if (debugChangesActive) Debug.Log(NodeLogger($"Tick", $"changed to {myNodeRuntimeData.nodeResult}"));
taskController.SetUiUpdate();
}
yield return myNodeRuntimeData.nodeResult;
// this should not be run again if it isnt in runnning mode anymore
if (myNodeRuntimeData.nodeState == NodeState.Running) {
if (debugChangesActive) Debug.Log(NodeLogger($"Tick.Cleanup", $"changed to {myNodeRuntimeData.nodeResult}"));
myNodeRuntimeData.taskHasChanges = PreTick(NodeExecute.Run, myNodeRuntimeData);
}
else {
if (debugChangesActive) Debug.Log(NodeLogger($"Tick.Cleanup", $"Testing, should be executed once after success of enumerator"));
}
}
}
}
else {
Debug.LogError(NodeLogger("RunTreeNode.Tick", $"recursions {recursions} childCount {children.Count}"));
taskController.SetUiUpdate();
yield return NodeResult.Error;
}
yield break;
}
public override string ToString() {
return base.ToString() + " thisId: " + this.GetInstanceID();
}
public override Node Duplicate() {
TreeNode tn = ScriptableObject.CreateInstance<TreeNode>();
base.BaseDuplicate(tn);
// TreeNode tn = base.Duplicate() as TreeNode;
tn.treeNodeName = treeNodeName;
return tn;
}
}
}