From ede650c36925316d111e2f8b13eaebb23bf7b0b3 Mon Sep 17 00:00:00 2001 From: Lumos Date: Sat, 21 Dec 2019 20:33:34 +0100 Subject: [PATCH 1/3] Added a big "edit graph" button to Node and Graph inspectors. I was very confused that this isn't a thing already. --- Scripts/Editor/GraphAndNodeEditor.cs | 128 ++++++++++++++++++++++ Scripts/Editor/GraphAndNodeEditor.cs.meta | 11 ++ 2 files changed, 139 insertions(+) create mode 100644 Scripts/Editor/GraphAndNodeEditor.cs create mode 100644 Scripts/Editor/GraphAndNodeEditor.cs.meta diff --git a/Scripts/Editor/GraphAndNodeEditor.cs b/Scripts/Editor/GraphAndNodeEditor.cs new file mode 100644 index 0000000..b2cc1c1 --- /dev/null +++ b/Scripts/Editor/GraphAndNodeEditor.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace XNodeEditor { + + [CustomEditor(typeof(XNode.NodeGraph), true)] + public class GlobalGraphEditor : Editor { + public override void OnInspectorGUI() { + serializedObject.Update(); + + var graphObject = serializedObject.targetObject as XNode.NodeGraph; + + var button = GUILayout.Button("Edit graph", GUILayout.Height(40)); + if (button && graphObject != null) { + NodeEditorWindow.Open(graphObject); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + GUILayout.Label("Raw data", "BoldLabel"); + + DrawDefaultInspector(); + + serializedObject.ApplyModifiedProperties(); + } + } + + + [CustomEditor(typeof(XNode.Node), true)] + public class GlobalNodeEditor : Editor { + private SerializedProperty graph; + + private void OnEnable() { + graph = serializedObject.FindProperty("graph"); + } + + public override void OnInspectorGUI() { + serializedObject.Update(); + + var graphObject = GetTargetObjectOfProperty(graph) as XNode.NodeGraph; + + var button = GUILayout.Button("Edit graph", GUILayout.Height(40)); + if (button && graphObject != null) { + NodeEditorWindow.Open(graphObject); + } + + GUILayout.Space(EditorGUIUtility.singleLineHeight); + GUILayout.Label("Raw data", "BoldLabel"); + + // Now draw the node itself. + DrawDefaultInspector(); + + serializedObject.ApplyModifiedProperties(); + } + + + + // HELPER METHODS BELOW RETRIEVED FROM https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBaseEditor/EditorHelper.cs + // BASED ON POST https://forum.unity.com/threads/get-a-general-object-value-from-serializedproperty.327098/#post-2309545 + // AND ADJUSTED SLIGHTLY AFTERWARDS + + /// + /// Gets the object the property represents. + /// + /// + /// + private static object GetTargetObjectOfProperty(SerializedProperty prop) { + if (prop == null) return null; + + var path = prop.propertyPath.Replace(".Array.data[", "["); + object obj = prop.serializedObject.targetObject; + var elements = path.Split('.'); + foreach (var element in elements) { + if (element.Contains("[")) { + var elementName = element.Substring(0, element.IndexOf("[", StringComparison.Ordinal)); + var index = Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.Ordinal)) + .Replace("[", "") + .Replace("]", "")); + obj = GetValue_Imp(obj, elementName, index); + } + else { + obj = GetValue_Imp(obj, element); + } + } + + return obj; + } + + private static object GetValue_Imp(object source, string name) { + if (source == null) + return null; + var type = source.GetType(); + + while (type != null) { + var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (f != null) + return f.GetValue(source); + + var p = type.GetProperty(name, + BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + if (p != null) + return p.GetValue(source, null); + + type = type.BaseType; + } + + return null; + } + + private static object GetValue_Imp(object source, string name, int index) { + if (!(GetValue_Imp(source, name) is IEnumerable enumerable)) return null; + var enm = enumerable.GetEnumerator(); + //while (index-- >= 0) + // enm.MoveNext(); + //return enm.Current; + + for (var i = 0; i <= index; i++) { + if (!enm.MoveNext()) return null; + } + + return enm.Current; + } + } + +} diff --git a/Scripts/Editor/GraphAndNodeEditor.cs.meta b/Scripts/Editor/GraphAndNodeEditor.cs.meta new file mode 100644 index 0000000..5cc60df --- /dev/null +++ b/Scripts/Editor/GraphAndNodeEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdd6e443125ccac4dad0665515759637 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 1d43244a8f1f8e0726de608dc862ec50a2fafe3c Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 23 Dec 2019 13:52:53 +0100 Subject: [PATCH 2/3] Simplified implementation --- Scripts/Editor/GraphAndNodeEditor.cs | 101 +++------------------------ 1 file changed, 10 insertions(+), 91 deletions(-) diff --git a/Scripts/Editor/GraphAndNodeEditor.cs b/Scripts/Editor/GraphAndNodeEditor.cs index b2cc1c1..6b4f12d 100644 --- a/Scripts/Editor/GraphAndNodeEditor.cs +++ b/Scripts/Editor/GraphAndNodeEditor.cs @@ -6,45 +6,33 @@ using UnityEditor; using UnityEngine; namespace XNodeEditor { - + /// Override graph inspector to show an 'Open Graph' button at the top [CustomEditor(typeof(XNode.NodeGraph), true)] public class GlobalGraphEditor : Editor { public override void OnInspectorGUI() { serializedObject.Update(); - var graphObject = serializedObject.targetObject as XNode.NodeGraph; - - var button = GUILayout.Button("Edit graph", GUILayout.Height(40)); - if (button && graphObject != null) { - NodeEditorWindow.Open(graphObject); + if (GUILayout.Button("Edit graph", GUILayout.Height(40))) { + NodeEditorWindow.Open(serializedObject.targetObject as XNode.NodeGraph); } - + GUILayout.Space(EditorGUIUtility.singleLineHeight); GUILayout.Label("Raw data", "BoldLabel"); DrawDefaultInspector(); - + serializedObject.ApplyModifiedProperties(); } } - [CustomEditor(typeof(XNode.Node), true)] public class GlobalNodeEditor : Editor { - private SerializedProperty graph; - - private void OnEnable() { - graph = serializedObject.FindProperty("graph"); - } - public override void OnInspectorGUI() { serializedObject.Update(); - var graphObject = GetTargetObjectOfProperty(graph) as XNode.NodeGraph; - - var button = GUILayout.Button("Edit graph", GUILayout.Height(40)); - if (button && graphObject != null) { - NodeEditorWindow.Open(graphObject); + if (GUILayout.Button("Edit graph", GUILayout.Height(40))) { + SerializedProperty graphProp = serializedObject.FindProperty("graph"); + NodeEditorWindow.Open(graphProp.objectReferenceValue as XNode.NodeGraph); } GUILayout.Space(EditorGUIUtility.singleLineHeight); @@ -52,77 +40,8 @@ namespace XNodeEditor { // Now draw the node itself. DrawDefaultInspector(); - + serializedObject.ApplyModifiedProperties(); } - - - - // HELPER METHODS BELOW RETRIEVED FROM https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBaseEditor/EditorHelper.cs - // BASED ON POST https://forum.unity.com/threads/get-a-general-object-value-from-serializedproperty.327098/#post-2309545 - // AND ADJUSTED SLIGHTLY AFTERWARDS - - /// - /// Gets the object the property represents. - /// - /// - /// - private static object GetTargetObjectOfProperty(SerializedProperty prop) { - if (prop == null) return null; - - var path = prop.propertyPath.Replace(".Array.data[", "["); - object obj = prop.serializedObject.targetObject; - var elements = path.Split('.'); - foreach (var element in elements) { - if (element.Contains("[")) { - var elementName = element.Substring(0, element.IndexOf("[", StringComparison.Ordinal)); - var index = Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.Ordinal)) - .Replace("[", "") - .Replace("]", "")); - obj = GetValue_Imp(obj, elementName, index); - } - else { - obj = GetValue_Imp(obj, element); - } - } - - return obj; - } - - private static object GetValue_Imp(object source, string name) { - if (source == null) - return null; - var type = source.GetType(); - - while (type != null) { - var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - if (f != null) - return f.GetValue(source); - - var p = type.GetProperty(name, - BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); - if (p != null) - return p.GetValue(source, null); - - type = type.BaseType; - } - - return null; - } - - private static object GetValue_Imp(object source, string name, int index) { - if (!(GetValue_Imp(source, name) is IEnumerable enumerable)) return null; - var enm = enumerable.GetEnumerator(); - //while (index-- >= 0) - // enm.MoveNext(); - //return enm.Current; - - for (var i = 0; i <= index; i++) { - if (!enm.MoveNext()) return null; - } - - return enm.Current; - } } - -} +} \ No newline at end of file From 5597e565d124751c0c836d0b44f50644a1249a9c Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 23 Dec 2019 13:56:49 +0100 Subject: [PATCH 3/3] Added focus selected node --- Scripts/Editor/GraphAndNodeEditor.cs | 3 ++- Scripts/Editor/NodeEditorWindow.cs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Scripts/Editor/GraphAndNodeEditor.cs b/Scripts/Editor/GraphAndNodeEditor.cs index 6b4f12d..bfc809a 100644 --- a/Scripts/Editor/GraphAndNodeEditor.cs +++ b/Scripts/Editor/GraphAndNodeEditor.cs @@ -32,7 +32,8 @@ namespace XNodeEditor { if (GUILayout.Button("Edit graph", GUILayout.Height(40))) { SerializedProperty graphProp = serializedObject.FindProperty("graph"); - NodeEditorWindow.Open(graphProp.objectReferenceValue as XNode.NodeGraph); + NodeEditorWindow w = NodeEditorWindow.Open(graphProp.objectReferenceValue as XNode.NodeGraph); + w.Home(); // Focus selected node } GUILayout.Space(EditorGUIUtility.singleLineHeight); diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index a063410..1f64653 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -187,12 +187,13 @@ namespace XNodeEditor { } /// Open the provided graph in the NodeEditor - public static void Open(XNode.NodeGraph graph) { - if (!graph) return; + public static NodeEditorWindow Open(XNode.NodeGraph graph) { + if (!graph) return null; NodeEditorWindow w = GetWindow(typeof(NodeEditorWindow), false, "xNode", true) as NodeEditorWindow; w.wantsMouseMove = true; w.graph = graph; + return w; } /// Repaint all open NodeEditorWindows.