using UnityEngine; using Hivemind; using System.Collections.Generic; using System.Collections; using Coolape; namespace Hivemind { [System.Serializable] public class Node : ScriptableObject, System.IComparable { public string condition = ""; public string result1 = ""; public string result2 = ""; // Editor settings [SerializeField] public Vector2 editorPosition; public int id; public int index = 0; public bool canMultTimes = false; public string desc = ""; // The Behavior Tree this node belongs too public BehaviorTree behaviorTree; // Used by the debugger to visually display the last status returned public Status? lastStatus; public int lastTick = 0; public Node() { id = GetInstanceID(); } // 要结束的节点 public List KillNodes = new List(); public List ParentKillNodes = new List(); public virtual void ConnectKillChild(Node child) { if (!KillNodes.Contains(child) && !Children.Contains(child)) { KillNodes.Add(child); child.ParentKillNodes.Add(this); } } public virtual void DisconnectKillChild(Node child) { if (KillNodes.Contains(child)) { KillNodes.Remove(child); child.ParentKillNodes.Remove(this); } } // Child connections public virtual void ConnectChild(Node child) { if (child == null) return; if (!Children.Contains(child) && !Children.Contains(child)) { Children.Add(child); child.setParent(this); } } public virtual void DisconnectChild(Node child) { if (Children.Contains(child)) { Children.Remove(child); child.Unparent(this); } } [SerializeField] List _children = new List(); public virtual List Children { get { return _children; } } public virtual int ChildCount { get { return Children.Count; } } public virtual bool CanConnectChild { get { return true; } } public virtual bool ContainsChild(Node child) { if (child == null) return false; return Children.Contains(child); } // IComparable for sorting left-to-right in the visual editor public int CompareTo(object other) { Node otherNode = other as Node; return editorPosition.x < otherNode.editorPosition.x ? -1 : 1; } // Parent connections [SerializeField] List _parents = new List(); public virtual List parents { get { return _parents; } } public virtual void setParent(Node parent) { if (!parents.Contains(parent)) { parents.Add(parent); } } public virtual void Unparent() { for (int i = parents.Count - 1; i >= 0; i--) { Unparent(parents [i]); } } public virtual void Unparent(Node parent) { if (parent == null) return; if (!parents.Contains(parent)) { return; } if (parent != null) { parents.Remove(parent); parent.DisconnectChild(this); } else { Debug.LogWarning(string.Format("Attempted unparenting {0} while it has no parent")); } } // All connections public virtual void Disconnect() { // Disconnect parent Node parent = null; for (int i = 0; i < parents.Count; i++) { parent = parents [i]; if (parent != null) { Unparent(parent); } } parents.Clear(); // Disconnect children if (ChildCount > 0) { for (int i = ChildCount - 1; i >= 0; i--) { DisconnectChild(Children [i]); } } for (int i = KillNodes.Count - 1; i >= 0; i--) { DisconnectKillChild(KillNodes [i]); } Node killNode = null; for (int i = ParentKillNodes.Count - 1; i >= 0; i--) { killNode = ParentKillNodes [i]; killNode.DisconnectKillChild(this); if(killNode is NodeBranch) { NodeBranch branch = killNode as NodeBranch; branch.DisconnectKillLeftChild(this); branch.DisconnectKillRightChild(this); } } } // Lifecycle public void OnEnable() { hideFlags = HideFlags.HideAndDontSave; } // Runtime public virtual Status Tick(GameObject agent, Context context) { return Status.Error; } public virtual void Deserialize(Hashtable map) { float x = float.Parse(map ["editorx"].ToString()); float y = float.Parse(map ["editory"].ToString()); editorPosition = new Vector2(x, y); id = MapEx.getInt(map, "id"); desc = MapEx.getString(map, "desc"); index = MapEx.getInt(map, "index"); canMultTimes = MapEx.getBool(map, "canMultTimes"); } public virtual void DeserializeChildren(Hashtable map) { ArrayList list = MapEx.getList(map, "Children"); Node node = null; for (int i = 0; i < list.Count; i++) { int id = int.Parse(list [i].ToString()); node = behaviorTree.getNodeByID(id); ConnectChild(node); } list = MapEx.getList(map, "KillNodes"); node = null; for (int i = 0; i < list.Count; i++) { int id = int.Parse(list [i].ToString()); node = behaviorTree.getNodeByID(id); ConnectKillChild(node); } } public virtual Hashtable Serialize() { Hashtable m = new Hashtable(); m ["id"] = id; m ["editorx"] = editorPosition.x.ToString(); m ["editory"] = editorPosition.y.ToString(); ArrayList subNodes = new ArrayList(); for (int i = 0; i < ChildCount; i++) { subNodes.Add(Children [i].id); } m ["Children"] = subNodes; ArrayList subkillNodes = new ArrayList(); for (int i = 0; i < KillNodes.Count; i++) { subkillNodes.Add(KillNodes [i].id); } m ["KillNodes"] = subkillNodes; m ["type"] = GetType().ToString(); m ["desc"] = desc; m ["index"] = index; m ["canMultTimes"] = canMultTimes; return m; } } }