From f8a0bb8f7c7209536da17c7705c3e237c3e77a69 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Wed, 27 Sep 2017 23:41:01 +0200 Subject: [PATCH] Started work on NodeGraphExample --- Examples/NodeToy.meta | 9 ++ Examples/NodeToy/MathToyNodeGraph.cs | 9 ++ Examples/NodeToy/MathToyNodeGraph.cs.meta | 12 ++ Examples/NodeToy/NodeGraphExample.asset | Bin 0 -> 4220 bytes Examples/NodeToy/NodeGraphExample.asset.meta | 9 ++ Examples/Nodes/MathNode.cs | 8 +- Scripts/Editor/NodeEditor.cs | 135 ++++++++++--------- Scripts/Editor/NodeEditorWindow.cs | 6 +- Scripts/Node.cs | 6 +- Scripts/NodeGraph.cs | 24 +--- Scripts/NodePort.cs | 10 +- 11 files changed, 129 insertions(+), 99 deletions(-) create mode 100644 Examples/NodeToy.meta create mode 100644 Examples/NodeToy/MathToyNodeGraph.cs create mode 100644 Examples/NodeToy/MathToyNodeGraph.cs.meta create mode 100644 Examples/NodeToy/NodeGraphExample.asset create mode 100644 Examples/NodeToy/NodeGraphExample.asset.meta diff --git a/Examples/NodeToy.meta b/Examples/NodeToy.meta new file mode 100644 index 0000000..7340d7b --- /dev/null +++ b/Examples/NodeToy.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 52f863b8b4fc21f47b2af1dd63a719ff +folderAsset: yes +timeCreated: 1506460802 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Examples/NodeToy/MathToyNodeGraph.cs b/Examples/NodeToy/MathToyNodeGraph.cs new file mode 100644 index 0000000..8f89aa0 --- /dev/null +++ b/Examples/NodeToy/MathToyNodeGraph.cs @@ -0,0 +1,9 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// Defines an example nodegraph. +[CreateAssetMenu(fileName = "NodeGraphExample", menuName = "Node Graph/Example")] +public class NodeGraphExample : NodeGraph { + +} diff --git a/Examples/NodeToy/MathToyNodeGraph.cs.meta b/Examples/NodeToy/MathToyNodeGraph.cs.meta new file mode 100644 index 0000000..43c9d35 --- /dev/null +++ b/Examples/NodeToy/MathToyNodeGraph.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a6399826e2c44b447b32a3ed06646162 +timeCreated: 1506460823 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Examples/NodeToy/NodeGraphExample.asset b/Examples/NodeToy/NodeGraphExample.asset new file mode 100644 index 0000000000000000000000000000000000000000..d703c11eac9c6041bef054fd852b46224ce23a95 GIT binary patch literal 4220 zcmeH~O-mb56o${uB!1MY{nFO@g*!J5nOX>hA`zRa6iQ0hA`wRt$rm%BM6hsI{T*F( zQ{40ybkV<%ZGS+w?mNEk%w)Ku;M&DKaB^p!d+vMByq7Gli1StC(S?XS#)v`Wb;&Ik z-J*Ny%KtD7l>+lQ5r+J|E7mbtLUPHZ5?vP2kcii5awR_;(Z4X4PwH4p&KQ9|#F#_I zJSTslv50rpI|eU8hx<(>b7P%vInjR-oq|zs>P#5i)R|1Vk~h%#lIU=cooFuG&$Pi! zod+pb@*RC1LWlj$Py<3^A3lKdyZFuH{+rnMU$XBkI77h^v;Vn>#oXL?KIKaGvF}gl z(0?AR(owx~;U|+EXD+Hr?nL^_Si^pvkVomrC)A!H`TjKJvHn(~|BPH~_L!Z2VOU5^}5^AIeOn}dk63EP;U&HcnFTVy%R5pw4{1< ziRE$dk7vU=U>&dySO=^F)&c8)b-+4c9k34ECkJ>5x*5Dwe#EtA&u{dbwPB;vZ+jbH YJ3-)ej@#$2c0V^8e!o(=S(FG}18xkDPyhe` literal 0 HcmV?d00001 diff --git a/Examples/NodeToy/NodeGraphExample.asset.meta b/Examples/NodeToy/NodeGraphExample.asset.meta new file mode 100644 index 0000000..e7e9fda --- /dev/null +++ b/Examples/NodeToy/NodeGraphExample.asset.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 84fbc8acdc9656941b529a16e8bbe318 +timeCreated: 1506462197 +licenseType: Free +NativeFormatImporter: + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Examples/Nodes/MathNode.cs b/Examples/Nodes/MathNode.cs index ae1e84b..175197d 100644 --- a/Examples/Nodes/MathNode.cs +++ b/Examples/Nodes/MathNode.cs @@ -1,4 +1,6 @@ -[System.Serializable] +using UnityEngine; + +[System.Serializable] public class MathNode : Node { [Input] public float a; [Input] public float b; @@ -9,4 +11,8 @@ public class MathNode : Node { protected override void Init() { name = "Math"; } + + public override void OnCreateConnection(NodePort from, NodePort to) { + + } } diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index c49fe99..6d825a6 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -14,7 +14,7 @@ public class NodeEditor { public virtual void OnNodeGUI() { portRects.Clear(); DrawDefaultNodePortsGUI(); - DrawDefaultNodeBody(); + DrawDefaultNodeBodyGUI(); } /// Draws standard editors for all fields marked with or @@ -42,75 +42,12 @@ public class NodeEditor { } /// Draws standard field editors for all public fields - protected void DrawDefaultNodeBody() { + protected void DrawDefaultNodeBodyGUI() { FieldInfo[] fields = GetInspectorFields(target); for (int i = 0; i < fields.Length; i++) { - Type fieldType = fields[i].FieldType; - string fieldName = fields[i].Name; - string fieldPrettyName = fieldName.PrettifyCamelCase(); - object fieldValue = fields[i].GetValue(target); object[] fieldAttribs = fields[i].GetCustomAttributes(false); - - HeaderAttribute headerAttrib; - if (NodeEditorUtilities.GetAttrib(fieldAttribs, out headerAttrib)) { - EditorGUILayout.LabelField(headerAttrib.header); - } - - //Skip if field has input or output attribute if (NodeEditorUtilities.HasAttrib(fieldAttribs) || NodeEditorUtilities.HasAttrib(fieldAttribs)) continue; - - EditorGUI.BeginChangeCheck(); - if (fieldType == typeof(int)) { - fieldValue = EditorGUILayout.IntField(fieldPrettyName, (int)fieldValue); - } - else if (fieldType == typeof(bool)) { - fieldValue = EditorGUILayout.Toggle(fieldPrettyName, (bool)fieldValue); - } - else if (fieldType.IsEnum) { - fieldValue = EditorGUILayout.EnumPopup(fieldPrettyName, (Enum)fieldValue); - } - else if (fieldType == typeof(string)) { - - if (fieldName == "name") continue; //Ignore 'name' - TextAreaAttribute textAreaAttrib; - if (NodeEditorUtilities.GetAttrib(fieldAttribs, out textAreaAttrib)) { - fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : ""); - } - else - fieldValue = EditorGUILayout.TextField(fieldPrettyName, fieldValue != null ? (string)fieldValue : ""); - } - else if (fieldType == typeof(Rect)) { - if (fieldName == "position") continue; //Ignore 'position' - fieldValue = EditorGUILayout.RectField(fieldPrettyName, (Rect)fieldValue); - } - else if (fieldType == typeof(float)) { - fieldValue = EditorGUILayout.FloatField(fieldPrettyName, (float)fieldValue); - } - else if (fieldType == typeof(Vector2)) { - fieldValue = EditorGUILayout.Vector2Field(fieldPrettyName, (Vector2)fieldValue); - } - else if (fieldType == typeof(Vector3)) { - fieldValue = EditorGUILayout.Vector3Field(new GUIContent(fieldPrettyName), (Vector3)fieldValue); - } - else if (fieldType == typeof(Vector4)) { - fieldValue = EditorGUILayout.Vector4Field(fieldPrettyName, (Vector4)fieldValue); - } - else if (fieldType == typeof(Color)) { - fieldValue = EditorGUILayout.ColorField(fieldPrettyName, (Color)fieldValue); - } - else if (fieldType == typeof(AnimationCurve)) { - AnimationCurve curve = fieldValue != null ? (AnimationCurve)fieldValue : new AnimationCurve(); - curve = EditorGUILayout.CurveField(fieldPrettyName, curve); - if (fieldValue != curve) fields[i].SetValue(target, curve); - } - else if (fieldType.IsSubclassOf(typeof(UnityEngine.Object)) || fieldType == typeof(UnityEngine.Object)) { - if (fieldName == "graph") continue; //Ignore 'graph' - fieldValue = EditorGUILayout.ObjectField(fieldPrettyName, (UnityEngine.Object)fieldValue, fieldType, true); - } - - if (EditorGUI.EndChangeCheck()) { - fields[i].SetValue(target, fieldValue); - } + DrawFieldInfoDrawerGUI(fields[i]); } EditorGUILayout.Space(); } @@ -145,6 +82,72 @@ public class NodeEditor { private static FieldInfo[] GetInspectorFields(Node node) { return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField),false) != null).ToArray(); } + + private void DrawFieldInfoDrawerGUI(FieldInfo fieldInfo) { + Type fieldType = fieldInfo.FieldType; + string fieldName = fieldInfo.Name; + string fieldPrettyName = fieldName.PrettifyCamelCase(); + object fieldValue = fieldInfo.GetValue(target); + object[] fieldAttribs = fieldInfo.GetCustomAttributes(false); + + HeaderAttribute headerAttrib; + if (NodeEditorUtilities.GetAttrib(fieldAttribs, out headerAttrib)) { + EditorGUILayout.LabelField(headerAttrib.header); + } + + EditorGUI.BeginChangeCheck(); + if (fieldType == typeof(int)) { + fieldValue = EditorGUILayout.IntField(fieldPrettyName, (int)fieldValue); + } + else if (fieldType == typeof(bool)) { + fieldValue = EditorGUILayout.Toggle(fieldPrettyName, (bool)fieldValue); + } + else if (fieldType.IsEnum) { + fieldValue = EditorGUILayout.EnumPopup(fieldPrettyName, (Enum)fieldValue); + } + else if (fieldType == typeof(string)) { + + if (fieldName == "name") return; //Ignore 'name' + TextAreaAttribute textAreaAttrib; + if (NodeEditorUtilities.GetAttrib(fieldAttribs, out textAreaAttrib)) { + fieldValue = EditorGUILayout.TextArea(fieldValue != null ? (string)fieldValue : ""); + } + else + fieldValue = EditorGUILayout.TextField(fieldPrettyName, fieldValue != null ? (string)fieldValue : ""); + } + else if (fieldType == typeof(Rect)) { + if (fieldName == "position") return; //Ignore 'position' + fieldValue = EditorGUILayout.RectField(fieldPrettyName, (Rect)fieldValue); + } + else if (fieldType == typeof(float)) { + fieldValue = EditorGUILayout.FloatField(fieldPrettyName, (float)fieldValue); + } + else if (fieldType == typeof(Vector2)) { + fieldValue = EditorGUILayout.Vector2Field(fieldPrettyName, (Vector2)fieldValue); + } + else if (fieldType == typeof(Vector3)) { + fieldValue = EditorGUILayout.Vector3Field(new GUIContent(fieldPrettyName), (Vector3)fieldValue); + } + else if (fieldType == typeof(Vector4)) { + fieldValue = EditorGUILayout.Vector4Field(fieldPrettyName, (Vector4)fieldValue); + } + else if (fieldType == typeof(Color)) { + fieldValue = EditorGUILayout.ColorField(fieldPrettyName, (Color)fieldValue); + } + else if (fieldType == typeof(AnimationCurve)) { + AnimationCurve curve = fieldValue != null ? (AnimationCurve)fieldValue : new AnimationCurve(); + curve = EditorGUILayout.CurveField(fieldPrettyName, curve); + if (fieldValue != curve) fieldInfo.SetValue(target, curve); + } + else if (fieldType.IsSubclassOf(typeof(UnityEngine.Object)) || fieldType == typeof(UnityEngine.Object)) { + if (fieldName == "graph") return; //Ignore 'graph' + fieldValue = EditorGUILayout.ObjectField(fieldPrettyName, (UnityEngine.Object)fieldValue, fieldType, true); + } + + if (EditorGUI.EndChangeCheck()) { + fieldInfo.SetValue(target, fieldValue); + } + } } [AttributeUsage(AttributeTargets.Class)] diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index a1974b3..13f1f5f 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -18,9 +18,9 @@ public partial class NodeEditorWindow : EditorWindow { private float _zoom = 1; partial void OnEnable(); - - [MenuItem("Window/UNEC")] - static NodeEditorWindow Init() { + /// Create editor window + //[MenuItem("Window/UNEC")] + public static NodeEditorWindow Init() { NodeEditorWindow w = CreateInstance(); w.titleContent = new GUIContent("UNEC"); w.wantsMouseMove = true; diff --git a/Scripts/Node.cs b/Scripts/Node.cs index 7217c90..dc1e42c 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -26,9 +26,11 @@ public abstract class Node { } /// Initialize node. Called on creation. - protected virtual void Init() { + protected virtual void Init() { } - } + /// Called whenever a connection is being made between two s + /// Output Input + public virtual void OnCreateConnection(NodePort from, NodePort to) { } public int GetInputId(NodePort input) { for (int i = 0; i < inputs.Length; i++) { diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs index 86f534a..c8cf56c 100644 --- a/Scripts/NodeGraph.cs +++ b/Scripts/NodeGraph.cs @@ -13,26 +13,11 @@ public abstract class NodeGraph : ScriptableObject { [SerializeField] public string[] s_nodes; public T AddNode() where T : Node { - T node = default(T); - return AddNode(node) as T; + return AddNode(typeof(T)) as T; } - public Node AddNode(Type type) { + public virtual Node AddNode(Type type) { Node node = (Node)Activator.CreateInstance(type); - return AddNode(node); - } - - public Node AddNode(string type) { - Debug.Log(type); - Node node = (Node)Activator.CreateInstance(null,type).Unwrap(); - return AddNode(node); - } - - public Node AddNode(Node node) { - if (node == null) { - Debug.LogError("Node could node be instanced"); - return null; - } nodes.Add(node); node.graph = this; return node; @@ -45,12 +30,9 @@ public abstract class NodeGraph : ScriptableObject { nodes.Remove(node); } + /// Remove all nodes and connections from the graph public void Clear() { nodes.Clear(); } - - private class NodeTyper { - public string nodeType = "Node"; - } } diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs index 064830b..bf626e5 100644 --- a/Scripts/NodePort.cs +++ b/Scripts/NodePort.cs @@ -37,6 +37,8 @@ public class NodePort { _direction = direction; } + /// Connect this to another + /// The to connect to public void Connect(NodePort port) { if (connections == null) connections = new List(); if (port == null) { Debug.LogWarning("Cannot connect to null port"); return; } @@ -45,6 +47,8 @@ public class NodePort { if (direction == port.direction) { Debug.LogWarning("Cannot connect two " + (direction == IO.Input ? "input" : "output") + " connections"); return; } connections.Add(port); port.connections.Add(this); + node.OnCreateConnection(this, port); + port.node.OnCreateConnection(this, port); } public NodePort GetConnection(int i) { @@ -66,10 +70,4 @@ public class NodePort { } connections.Clear(); } - - [Serializable] - private class PortID { - public int nodeID; - public int portID; - } }