diff --git a/Scripts/Editor/NodeEditorUtilities.cs b/Scripts/Editor/NodeEditorUtilities.cs
index d0cbc7b..67d18d0 100644
--- a/Scripts/Editor/NodeEditorUtilities.cs
+++ b/Scripts/Editor/NodeEditorUtilities.cs
@@ -48,8 +48,8 @@ namespace XNodeEditor {
);
return methods.Count() > 0;
}
-
- /// Return a prettiefied type name.
+
+ /// Return a prettified type name.
public static string PrettyName(this Type type) {
if (type == null) return "null";
if (type == typeof(System.Object)) return "object";
diff --git a/Scripts/Editor/NodeGraphInspector.cs b/Scripts/Editor/NodeGraphInspector.cs
new file mode 100644
index 0000000..135277a
--- /dev/null
+++ b/Scripts/Editor/NodeGraphInspector.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+using XNode;
+using XNodeEditor;
+
+[CustomEditor(typeof(XNode.NodeGraph), true)]
+public class NodeGraphInspector : Editor
+{
+ SerializedProperty nodesProp;
+ SerializedProperty variablesProp;
+
+ void OnEnable()
+ {
+ nodesProp = serializedObject.FindProperty("nodes");
+ variablesProp = serializedObject.FindProperty("variables");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ DrawVariables();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ void DrawVariables()
+ {
+ EditorGUILayout.LabelField("Variables");
+ EditorGUILayout.Space();
+ for (int i = 0; i < variablesProp.arraySize; i++)
+ DrawVariable(i);
+ DrawVariablesActions();
+ }
+
+ void DrawVariable(int index)
+ {
+ var variableProp = variablesProp.GetArrayElementAtIndex(index);
+
+ var idProp = variableProp.FindPropertyRelative("id");
+ var typeProp = variableProp.FindPropertyRelative("typeString");
+
+
+ DrawVariableId(idProp);
+ DrawVariableType(typeProp);
+ DrawVariableValue(variableProp, typeProp.stringValue);
+ DrawVariableActions(index);
+
+ EditorGUILayout.Space();
+ }
+
+ void DrawVariableId(SerializedProperty idProp)
+ {
+ EditorGUILayout.PropertyField(idProp);
+ }
+
+ void DrawVariableType(SerializedProperty typeProp)
+ {
+ List options = new List();
+ options.Add(typeProp.stringValue);
+ int idx = 0;
+
+ List additionalTypes = new List();
+ additionalTypes.Add(typeof(float).AssemblyQualifiedName);
+ additionalTypes.Add(typeof(int).AssemblyQualifiedName);
+ additionalTypes.Add(typeof(bool).AssemblyQualifiedName);
+ additionalTypes.Add(typeof(string).AssemblyQualifiedName);
+ additionalTypes.Add(typeof(Vector3).AssemblyQualifiedName);
+
+ /*
+ Assembly asm = typeof(Vector3).Assembly;
+ foreach (var colorPair in NodeEditorPreferences.typeColors)
+ {
+ var type = asm.GetType(colorPair.Key, false);
+ Debug.Log(colorPair.Key + " " + type);
+
+ if (type == null)
+ continue;
+ if (additionalTypes.Contains(type.AssemblyQualifiedName))
+ continue;
+ additionalTypes.Add(colorPair.Key);
+ }
+ */
+
+ foreach (var addType in additionalTypes)
+ {
+ if (!options.Contains(addType))
+ options.Add(addType);
+ }
+
+ List prettyOptions = new List();
+
+ foreach (var option in options)
+ {
+ prettyOptions.Add(System.Type.GetType(option, false).PrettyName());
+ }
+
+
+ idx = EditorGUILayout.Popup(idx, prettyOptions.ToArray());
+
+ typeProp.stringValue = options[idx];
+ }
+
+ void DrawVariableValue(SerializedProperty variableProp, string type)
+ {
+ if (type != "")
+ {
+ type = System.Type.GetType(type, false).PrettyName();
+ type = NodeGraph.GetSafeType(type);
+
+ var valprop = variableProp.FindPropertyRelative(type + "Value");
+
+ if (valprop == null && type != "object")
+ {
+ type = "object";
+ valprop = variableProp.FindPropertyRelative(type + "Value");
+ }
+
+ if (valprop != null)
+ EditorGUILayout.PropertyField(valprop);
+ else
+ EditorGUILayout.LabelField("Value");
+ }
+ else
+ EditorGUILayout.LabelField("Value");
+ }
+
+ void DrawVariableActions(int index)
+ {
+ if (GUILayout.Button("Remove variable", GUILayout.Width(120)))
+ {
+ variablesProp.DeleteArrayElementAtIndex(index);
+ }
+ }
+
+ void DrawVariablesActions()
+ {
+ GUILayout.BeginHorizontal();
+
+ GUILayout.FlexibleSpace();
+ if (GUILayout.Button("Add new variable", GUILayout.Width(120)))
+ {
+ variablesProp.InsertArrayElementAtIndex(variablesProp.arraySize);
+ var newVarProp = variablesProp.GetArrayElementAtIndex(variablesProp.arraySize -1);
+ newVarProp.FindPropertyRelative("id").stringValue = (target as NodeGraph).GetSafeId("new_variable");
+ newVarProp.FindPropertyRelative("typeString").stringValue = typeof(float).AssemblyQualifiedName;
+ }
+
+ GUILayout.EndHorizontal();
+ }
+}
diff --git a/Scripts/Editor/NodeGraphInspector.cs.meta b/Scripts/Editor/NodeGraphInspector.cs.meta
new file mode 100644
index 0000000..58f2bd6
--- /dev/null
+++ b/Scripts/Editor/NodeGraphInspector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 16edf05454c66b04ba4ebd0bf5b0af6c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/NodeInspector.cs b/Scripts/Editor/NodeInspector.cs
new file mode 100644
index 0000000..da797cc
--- /dev/null
+++ b/Scripts/Editor/NodeInspector.cs
@@ -0,0 +1,12 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+using XNode;
+
+[CustomEditor(typeof(Node), true)]
+public class NodeInspector : Editor
+{
+ public override void OnInspectorGUI() { /*hides unneeded info*/ }
+}
diff --git a/Scripts/Editor/NodeInspector.cs.meta b/Scripts/Editor/NodeInspector.cs.meta
new file mode 100644
index 0000000..0faa43e
--- /dev/null
+++ b/Scripts/Editor/NodeInspector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a079842175cdba54a8c36ad52f983502
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Node.cs b/Scripts/Node.cs
index d65fc03..5bede6e 100644
--- a/Scripts/Node.cs
+++ b/Scripts/Node.cs
@@ -62,11 +62,11 @@ namespace XNode {
protected void OnEnable() {
NodeDataCache.UpdatePorts(this, ports);
- Init();
+ // Init();
}
/// Initialize node. Called on creation.
- protected virtual void Init() { name = GetType().Name; }
+ public virtual void Init() { name = GetType().Name; }
/// Checks all connections for invalid references, and removes them.
public void VerifyConnections() {
diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs
index c2092e0..f17d1f4 100644
--- a/Scripts/NodeGraph.cs
+++ b/Scripts/NodeGraph.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using System.Text.RegularExpressions;
using System.Collections.Generic;
using UnityEngine;
@@ -10,6 +12,9 @@ namespace XNode {
/// All nodes in the graph.
/// See:
[SerializeField] public List nodes = new List();
+
+ /// All variables in the graph.
+ [SerializeField] public List variables = new List();
/// Add a node to the graph by type
public T AddNode() where T : Node {
@@ -28,6 +33,7 @@ namespace XNode {
#endif
nodes.Add(node);
node.graph = this;
+ node.Init();
return node;
}
@@ -44,6 +50,7 @@ namespace XNode {
#endif
nodes.Add(node);
node.graph = this;
+ node.Init();
return node;
}
@@ -60,9 +67,10 @@ namespace XNode {
nodes.Remove(node);
}
- /// Remove all nodes and connections from the graph
+ /// Remove all nodes, connections and variables from the graph
public void Clear() {
nodes.Clear();
+ variables.Clear();
}
/// Create a new deep copy of this graph
@@ -74,6 +82,7 @@ namespace XNode {
Node node = Instantiate(nodes[i]) as Node;
node.graph = graph;
graph.nodes[i] = node;
+ node.Init();
}
// Redirect all connections
@@ -85,5 +94,60 @@ namespace XNode {
return graph;
}
+
+ /// Add a variable to the graph
+ /// the new variable data
+ /// the actual id used, avoiding duplicates
+ public string AddVariable(Variable newVariable)
+ {
+ newVariable.id = GetSafeId(newVariable.id);
+ newVariable.typeString = GetSafeType(newVariable.typeString);
+ variables.Add(newVariable);
+ return newVariable.id;
+ }
+
+ /// Remove a variable from the graph
+ public void RemoveVariable(string id)
+ {
+ variables.Remove(GetVariable(id));
+ }
+
+ /// Get a variable from the graph
+ public Variable GetVariable(string id)
+ {
+ return variables.Find((Variable v) => v.id == id);
+ }
+
+ /// Get a duplication safe id
+ public string GetSafeId(string id)
+ {
+ id = id.ToLower();
+ id.Trim();
+ var rx = new Regex(@"\s");
+ rx.Replace(id, new MatchEvaluator((Match m) => "_"));
+
+ var existingVariable = variables.Find((Variable v) => v.id == id);
+ if (existingVariable == null)
+ return id;
+
+ int index = 1;
+
+ while (variables.Find((Variable v) => v.id == id + "_" + index.ToString()) != null)
+ index++;
+ return id + "_" + index.ToString();
+ }
+
+ /// Get a variable safe type
+ public static string GetSafeType(string type)
+ {
+ const string UE = "UnityEngine.";
+ if (type.Contains(UE))
+ {
+ type = type.Substring(UE.Length);
+ type = type.Substring(0,1).ToLower() + type.Substring(1);
+ }
+
+ return type;
+ }
}
}
\ No newline at end of file
diff --git a/Scripts/Variable.cs b/Scripts/Variable.cs
new file mode 100644
index 0000000..9d57c6c
--- /dev/null
+++ b/Scripts/Variable.cs
@@ -0,0 +1,52 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+[System.Serializable]
+public class Variable
+{
+ public string id;
+ public string typeString;
+ public System.Type type
+ {
+ get
+ {
+ if (typeString == typeof(float).AssemblyQualifiedName) return typeof(float);
+ if (typeString == typeof(int).AssemblyQualifiedName) return typeof(int);
+ if (typeString == typeof(string).AssemblyQualifiedName) return typeof(string);
+ if (typeString == typeof(bool).AssemblyQualifiedName) return typeof(bool);
+ if (typeString == typeof(Vector3).AssemblyQualifiedName) return typeof(Vector3);
+ return typeof(Object);
+ }
+ }
+
+ public object Value
+ {
+ get
+ {
+ if (typeString == typeof(float).AssemblyQualifiedName) return floatValue;
+ if (typeString == typeof(int).AssemblyQualifiedName) return intValue;
+ if (typeString == typeof(string).AssemblyQualifiedName) return stringValue;
+ if (typeString == typeof(bool).AssemblyQualifiedName) return boolValue;
+ if (typeString == typeof(Vector3).AssemblyQualifiedName) return vector3Value;
+ return objectValue;
+ }
+ }
+
+ public string stringValue;
+ public float floatValue;
+ public int intValue;
+ public bool boolValue;
+ public Vector3 vector3Value;
+
+ // more here
+
+ public Object objectValue;
+
+
+ public Variable()
+ {
+ id = "new_variable";
+ typeString = typeof(float).AssemblyQualifiedName;
+ }
+}
diff --git a/Scripts/Variable.cs.meta b/Scripts/Variable.cs.meta
new file mode 100644
index 0000000..a68dc79
--- /dev/null
+++ b/Scripts/Variable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 81f7d4c8803ebee4c903b0976f780d95
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: