//============= 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(RunTreeNode))] public class RunTreeNode : Node { // [SerializeField] public string runTreeNodeName; [SerializeField] public TreeNode runThisNode; public void Init(int _nodeDepth, Token[] _tokens, string _runTreeNodeName) { base.Init(_nodeDepth, _tokens); runTreeNodeName = _runTreeNodeName; } public override IEnumerable Tick(NodeRuntimeData parentNodeRuntimeData, int recursions = 0) { if (debugInternalActive) { Debug.Log(NodeLogger($"Tick", $"")); } if ((runThisNode != null) && (recursions < recursionLimit)) { using (NodeRuntimeData myNodeRuntimeData = new NodeRuntimeData(this, parentNodeRuntimeData)) { myNodeRuntimeData.tickExecuteEnumerator = runThisNode.Tick(myNodeRuntimeData, recursions + 1).GetEnumerator(); myNodeRuntimeData.taskHasChanges = base.PreTick(NodeExecute.Run, myNodeRuntimeData); while ((myNodeRuntimeData.tickExecuteEnumerator != null) && (myNodeRuntimeData.tickExecuteEnumerator.MoveNext())) { myNodeRuntimeData.nodeResult = myNodeRuntimeData.tickExecuteEnumerator.Current; if (debugInternalActive) Debug.Log(NodeLogger($"Tick", $"nodeResult {myNodeRuntimeData.tickExecuteEnumerator.Current}")); // return the same result as the child myNodeRuntimeData.taskHasChanges |= base.PostTick(NodeExecute.Run, myNodeRuntimeData); if (myNodeRuntimeData.taskHasChanges && taskController) { if (debugInternalActive) 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 (debugInternalActive) Debug.Log(NodeLogger($"Tick.Cleanup", $"changed to {myNodeRuntimeData.nodeResult}")); myNodeRuntimeData.taskHasChanges = PreTick(NodeExecute.Run, myNodeRuntimeData); } else { if (debugInternalActive) Debug.LogError(NodeLogger($"Tick.Cleanup", $"Testing, should be executed once after success of enumerator")); } } } } else { Debug.LogError(NodeLogger($"Tick", $"Reached maximum number of recursions {recursions} (runThisNode {(runThisNode != null ? $"{runThisNode}" : "undefined")})")); taskController.SetUiUpdate(); yield return NodeResult.Error; } yield break; } public override string ToString () { string runThisNodeId = (runThisNode!=null)?runThisNode.GetInstanceID().ToString():"undefined"; return base.ToString() + " runId: " + runThisNodeId; } public override Node Duplicate () { RunTreeNode tn = ScriptableObject.CreateInstance(); base.BaseDuplicate (tn); // RunTreeNode tn = base.Duplicate() as RunTreeNode; tn.runTreeNodeName = runTreeNodeName; tn.runThisNode = runThisNode; return tn; } } }