NodeGraph.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace XNode
  5. {
  6. /// <summary> Base class for all node graphs </summary>
  7. [Serializable]
  8. public abstract class NodeGraph : ScriptableObject
  9. {
  10. /// <summary> All nodes in the graph. <para/>
  11. /// See: <see cref="AddNode{T}"/> </summary>
  12. [SerializeField] public List<Node> nodes = new List<Node>();
  13. /// <summary> Add a node to the graph by type (convenience method - will call the System.Type version) </summary>
  14. public T AddNode<T>() where T : Node
  15. {
  16. return AddNode(typeof(T)) as T;
  17. }
  18. public virtual string Title()
  19. {
  20. return "xNode";
  21. }
  22. /// <summary> Add a node to the graph by type </summary>
  23. public virtual Node AddNode(Type type)
  24. {
  25. Node.graphHotfix = this;
  26. Node node = CreateInstance(type) as Node;
  27. node.UniqueID = node.GetInstanceID();
  28. node.graph = this;
  29. nodes.Add(node);
  30. return node;
  31. }
  32. /// <summary> Creates a copy of the original node in the graph </summary>
  33. public virtual Node CopyNode(Node original)
  34. {
  35. Node.graphHotfix = this;
  36. Node node = Instantiate(original);
  37. node.graph = this;
  38. node.ClearConnections();
  39. nodes.Add(node);
  40. return node;
  41. }
  42. /// <summary> Safely remove a node and all its connections </summary>
  43. /// <param name="node"> The node to remove </param>
  44. public virtual void RemoveNode(Node node)
  45. {
  46. node.ClearConnections();
  47. nodes.Remove(node);
  48. if (Application.isPlaying) Destroy(node);
  49. }
  50. /// <summary> Remove all nodes and connections from the graph </summary>
  51. public virtual void Clear()
  52. {
  53. // if (Application.isPlaying)
  54. // {
  55. // for (int i = 0; i < nodes.Count; i++)
  56. // {
  57. // DestroyImmediate(nodes[i], false);
  58. // }
  59. // }
  60. //
  61. // nodes.Clear();
  62. }
  63. /// <summary> Create a new deep copy of this graph </summary>
  64. public virtual NodeGraph Copy()
  65. {
  66. // Instantiate a new nodegraph instance
  67. NodeGraph graph = Instantiate(this);
  68. // Instantiate all nodes inside the graph
  69. for (int i = 0; i < nodes.Count; i++)
  70. {
  71. if (nodes[i] == null) continue;
  72. Node.graphHotfix = graph;
  73. Node node = Instantiate(nodes[i]) as Node;
  74. node.graph = graph;
  75. graph.nodes[i] = node;
  76. }
  77. // Redirect all connections
  78. for (int i = 0; i < graph.nodes.Count; i++)
  79. {
  80. if (graph.nodes[i] == null) continue;
  81. foreach (NodePort port in graph.nodes[i].Ports)
  82. {
  83. port.Redirect(nodes, graph.nodes);
  84. }
  85. }
  86. return graph;
  87. }
  88. protected virtual void OnDestroy()
  89. {
  90. // Remove all nodes prior to graph destruction
  91. // Clear();
  92. }
  93. #region Attributes
  94. /// <summary> Automatically ensures the existance of a certain node type, and prevents it from being deleted. </summary>
  95. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  96. public class RequireNodeAttribute : Attribute
  97. {
  98. public Type type0;
  99. public Type type1;
  100. public Type type2;
  101. /// <summary> Automatically ensures the existance of a certain node type, and prevents it from being deleted </summary>
  102. public RequireNodeAttribute(Type type)
  103. {
  104. this.type0 = type;
  105. this.type1 = null;
  106. this.type2 = null;
  107. }
  108. /// <summary> Automatically ensures the existance of a certain node type, and prevents it from being deleted </summary>
  109. public RequireNodeAttribute(Type type, Type type2)
  110. {
  111. this.type0 = type;
  112. this.type1 = type2;
  113. this.type2 = null;
  114. }
  115. /// <summary> Automatically ensures the existance of a certain node type, and prevents it from being deleted </summary>
  116. public RequireNodeAttribute(Type type, Type type2, Type type3)
  117. {
  118. this.type0 = type;
  119. this.type1 = type2;
  120. this.type2 = type3;
  121. }
  122. public bool Requires(Type type)
  123. {
  124. if (type == null) return false;
  125. if (type == type0) return true;
  126. else if (type == type1) return true;
  127. else if (type == type2) return true;
  128. return false;
  129. }
  130. }
  131. #endregion
  132. }
  133. }