86 lines
4.3 KiB
C#
86 lines
4.3 KiB
C#
//============= 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;
|
|
}
|
|
}
|
|
}
|