using System.Collections; using System.Collections.Generic; using UnityEngine; using XNode; using RPGCreationKit.BehaviourTree; using UnityEditor; namespace RPGCreationKit.BehaviourTree { /// /// This node selects randomly only one output and attempts to execute it. /// [CreateNodeMenu("RPGCK_BehaviourTree/RandomSelectOneNode", order = 1)] [System.Serializable] public class RandomSelectOneNode : BTNode { [Output(ShowBackingValue.Never, ConnectionType.Multiple, TypeConstraint.None)] public BTNode outputs; // Use this for initialization protected override void Init() { base.Init(); } public override void ReorderChild() { List endPorts = GetOutputPort("outputs").GetConnections(); List nodes = new List(); for (int i = 0; i < endPorts.Count; i++) nodes.Add((endPorts[i].node as BTNode)); nodes.Sort(SortInGraphYPos); for (int i = 0; i < nodes.Count; i++) { BTNode btNode = nodes[i] as BTNode; btNode.indexInSequence = i; } } // Return the correct value of an output port when requested public override object GetValue(NodePort port) { return null; // Replace this } public int outputToExecute = 0; public override NodeState Execute() { if (!STARTED) OnStart(); m_NodeState = NodeState.Running; List endPorts = GetOutputPort("outputs").GetConnections(); switch ((endPorts[outputToExecute].node as BTNode).Execute()) { case NodeState.Failure: break; case NodeState.Success: m_NodeState = NodeState.Success; return m_NodeState; case NodeState.Running: m_NodeState = NodeState.Running; return m_NodeState; default: break; } m_NodeState = NodeState.Failure; return m_NodeState; } public override void ReEvaluate() { base.ReEvaluate(); hasEvaluated = false; if (m_NodeState != NodeState.Running && m_NodeState != NodeState.Null) OnStart(); List endPorts = GetOutputPort("outputs").GetConnections(); for (int i = 0; i < endPorts.Count; i++) { (endPorts[i].node as BTNode).ReEvaluate(); } } public override void OnCreateConnection(NodePort from, NodePort to) { base.OnCreateConnection(from, to); #if UNITY_EDITOR EditorApplication.delayCall += ReorderChild; #endif } public override void OnRemoveConnection(NodePort port) { base.OnRemoveConnection(port); if (port.fieldName == "input") indexInSequence = -1; else if (port.fieldName == "outputs") { #if UNITY_EDITOR EditorApplication.delayCall += ReorderChild; #endif } } public override void OnStart() { outputToExecute = Random.Range(0, GetOutputPort("outputs").GetConnections().Count); STARTED = true; } } }