diff --git a/Examples/Nodes/Editor/MathNodeEditor.cs b/Examples/Nodes/Editor/MathNodeEditor.cs
index 38db27b..d244742 100644
--- a/Examples/Nodes/Editor/MathNodeEditor.cs
+++ b/Examples/Nodes/Editor/MathNodeEditor.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
-[CustomNodeEditor(typeof(MathNode))]
+[CustomNodeEditor(typeof(MathNode), "Math")]
public class AddNodeEditor : NodeEditor {
public override void OnNodeGUI() {
diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs
index 1df9ffb..ca6e1ad 100644
--- a/Scripts/Editor/NodeEditor.cs
+++ b/Scripts/Editor/NodeEditor.cs
@@ -7,7 +7,6 @@ using System.Linq;
using System;
/// Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes.
-[CustomNodeEditor(typeof(Node))]
public class NodeEditor {
public Node target;
@@ -26,7 +25,7 @@ public class NodeEditor {
object[] fieldAttribs = fields[i].GetCustomAttributes(false);
HeaderAttribute headerAttrib;
- if (GetAttrib(fieldAttribs, out headerAttrib)) {
+ if (NodeEditorUtilities.GetAttrib(fieldAttribs, out headerAttrib)) {
EditorGUILayout.LabelField(headerAttrib.header);
}
@@ -41,15 +40,17 @@ public class NodeEditor {
fieldValue = EditorGUILayout.EnumPopup(fieldName, (Enum)fieldValue);
}
else if (fieldType == typeof(string)) {
+
+ if (fieldName == "name") continue; //Ignore 'name'
TextAreaAttribute textAreaAttrib;
- if (GetAttrib(fieldAttribs, out textAreaAttrib)) {
+ if (NodeEditorUtilities.GetAttrib(fieldAttribs, out textAreaAttrib)) {
fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : "");
}
else
fieldValue = EditorGUILayout.TextField(fieldName, fieldValue != null ? (string)fieldValue : "");
}
else if (fieldType == typeof(Rect)) {
- if (fieldName == "position") continue;
+ if (fieldName == "position") continue; //Ignore 'position'
fieldValue = EditorGUILayout.RectField(fieldName, (Rect)fieldValue);
}
else if (fieldType == typeof(float)) {
@@ -80,28 +81,25 @@ public class NodeEditor {
fields[i].SetValue(target, fieldValue);
}
}
+ EditorGUILayout.Space();
}
private static FieldInfo[] GetInspectorFields(Node node) {
return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField),false) != null).ToArray();
}
-
- private static bool GetAttrib(object[] attribs, out T attribOut) where T : Attribute {
- for (int i = 0; i < attribs.Length; i++) {
- if (attribs[i].GetType() == typeof(T)) {
- attribOut = attribs[i] as T;
- return true;
- }
- }
- attribOut = null;
- return false;
- }
}
[AttributeUsage(AttributeTargets.Class)]
public class CustomNodeEditorAttribute : Attribute {
- public Type inspectedType;
- public CustomNodeEditorAttribute(Type inspectedType) {
- this.inspectedType = inspectedType;
+ public Type inspectedType { get { return _inspectedType; } }
+ private Type _inspectedType;
+ public string contextMenuName { get { return _contextMenuName; } }
+ private string _contextMenuName;
+ /// Tells a NodeEditor which Node type it is an editor for
+ /// Type that this editor can edit
+ /// Path to the node
+ public CustomNodeEditorAttribute(Type inspectedType, string contextMenuName) {
+ _inspectedType = inspectedType;
+ _contextMenuName = contextMenuName;
}
}
diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs
index d3ce874..4cef3e4 100644
--- a/Scripts/Editor/NodeEditorAction.cs
+++ b/Scripts/Editor/NodeEditorAction.cs
@@ -105,7 +105,7 @@ public partial class NodeEditorWindow {
}
}
else if (e.button == 1) {
- if (!isPanning) RightClickContextMenu();
+ if (!isPanning) ShowContextMenu();
isPanning = false;
}
UpdateHovered();
diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs
index 3acaffa..6e5ae5d 100644
--- a/Scripts/Editor/NodeEditorGUI.cs
+++ b/Scripts/Editor/NodeEditorGUI.cs
@@ -76,18 +76,26 @@ public partial class NodeEditorWindow {
return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width));
}
- public void RightClickContextMenu() {
+ /// Show right-click context menu
+ public void ShowContextMenu() {
GenericMenu contextMenu = new GenericMenu();
+ Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
if (hoveredNode != null) {
Node node = hoveredNode;
contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
}
else {
- Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
for (int i = 0; i < nodeTypes.Length; i++) {
Type type = nodeTypes[i];
- contextMenu.AddItem(new GUIContent(nodeTypes[i].ToString()), false, () => {
+ Type editorType = GetNodeEditor(type).GetType();
+
+ string name = nodeTypes[i].ToString().Replace('.', '/');
+ CustomNodeEditorAttribute attrib;
+ if (NodeEditorUtilities.GetAttrib(editorType, out attrib)) {
+ name = attrib.contextMenuName;
+ }
+ contextMenu.AddItem(new GUIContent(name), false, () => {
CreateNode(type, pos);
});
}
diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs
index ce7e7e8..2b8c46c 100644
--- a/Scripts/Editor/NodeEditorReflection.cs
+++ b/Scripts/Editor/NodeEditorReflection.cs
@@ -1,15 +1,14 @@
using System.Collections.Generic;
using System.Reflection;
-using System.Linq;
+using System.Linq;
using System;
using UnityEngine;
/// Contains reflection-related info
public partial class NodeEditorWindow {
-
- private static Dictionary customNodeEditor;
+ [NonSerialized] private static Dictionary customNodeEditor;
public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } }
- private static Type[] _nodeTypes;
+ [NonSerialized] private static Type[] _nodeTypes = null;
public static NodeEditor GetNodeEditor(Type node) {
if (customNodeEditor == null) CacheCustomNodeEditors();
@@ -30,6 +29,7 @@ public partial class NodeEditorWindow {
for (int i = 0; i < nodeEditors.Length; i++) {
var attribs = nodeEditors[i].GetCustomAttributes(typeof(CustomNodeEditorAttribute), false);
if (attribs == null || attribs.Length == 0) continue;
+ if (nodeEditors[i].IsAbstract) continue;
CustomNodeEditorAttribute attrib = attribs[0] as CustomNodeEditorAttribute;
customNodeEditor.Add(attrib.inspectedType, Activator.CreateInstance(nodeEditors[i]) as NodeEditor);
}
@@ -39,7 +39,7 @@ public partial class NodeEditorWindow {
//Get all classes deriving from baseType via reflection
Assembly assembly = Assembly.GetAssembly(baseType);
return assembly.GetTypes().Where(t =>
- t != baseType &&
+ !t.IsAbstract &&
baseType.IsAssignableFrom(t)
).ToArray();
}
diff --git a/Scripts/Editor/NodeEditorUtilities.cs b/Scripts/Editor/NodeEditorUtilities.cs
new file mode 100644
index 0000000..37af764
--- /dev/null
+++ b/Scripts/Editor/NodeEditorUtilities.cs
@@ -0,0 +1,23 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public static class NodeEditorUtilities {
+
+ public static bool GetAttrib(Type classType, out T attribOut) where T : Attribute {
+ object[] attribs = classType.GetCustomAttributes(typeof(T), false);
+ return GetAttrib(attribs, out attribOut);
+ }
+
+ public static bool GetAttrib(object[] attribs, out T attribOut) where T : Attribute {
+ for (int i = 0; i < attribs.Length; i++) {
+ if (attribs[i].GetType() == typeof(T)) {
+ attribOut = attribs[i] as T;
+ return true;
+ }
+ }
+ attribOut = null;
+ return false;
+ }
+}
diff --git a/Scripts/Editor/NodeEditorUtilities.cs.meta b/Scripts/Editor/NodeEditorUtilities.cs.meta
new file mode 100644
index 0000000..a8988ef
--- /dev/null
+++ b/Scripts/Editor/NodeEditorUtilities.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 120960fe5b50aba418a8e8ad3c4c4bc8
+timeCreated: 1506073499
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs
index 2423d8d..d830e7d 100644
--- a/Scripts/Editor/NodeEditorWindow.cs
+++ b/Scripts/Editor/NodeEditorWindow.cs
@@ -4,6 +4,7 @@ using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEditor.Callbacks;
+using System;
[InitializeOnLoad]
public partial class NodeEditorWindow : EditorWindow {