1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-03-26 22:49:02 +08:00

Merge 1a291335ee8bd5af482dbaa5dd58363dae4cca6f into 7985055bc75d52a979b9de550ac60204308cf981

This commit is contained in:
Joram Vandemoortele 2018-02-13 10:06:48 +00:00 committed by GitHub
commit 996bdec7c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 357 additions and 5 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -136,5 +137,29 @@ namespace XNodeEditor {
GUI.DrawTexture(rect, NodeEditorResources.dot); GUI.DrawTexture(rect, NodeEditorResources.dot);
GUI.color = col; GUI.color = col;
} }
/// <summary> Make a popup with all variable ids.</summary>
public static string VariablePopup(XNode.NodeGraph graph, string variableId, params GUILayoutOption[] options)
{
if (graph == null) return variableId;
List<string> variablesStrings = new List<string>();
foreach (var item in graph.variables)
variablesStrings.Add(item.id);
int originalIdx = variablesStrings.IndexOf(variableId);
int newIdx = EditorGUILayout.Popup(originalIdx, variablesStrings.ToArray(), options);
if (originalIdx == -1 && newIdx == -1)
{
EditorGUILayout.HelpBox("Looks like the variable that used to be here, doesn't exist anymore. \n id:" + variableId, MessageType.Error);
return variableId;
}
if (newIdx >= variablesStrings.Count)
return variableId;
return variablesStrings[newIdx];
}
} }
} }

View File

@ -48,8 +48,8 @@ namespace XNodeEditor {
); );
return methods.Count() > 0; return methods.Count() > 0;
} }
/// <summary> Return a prettiefied type name. </summary> /// <summary> Return a prettified type name. </summary>
public static string PrettyName(this Type type) { public static string PrettyName(this Type type) {
if (type == null) return "null"; if (type == null) return "null";
if (type == typeof(System.Object)) return "object"; if (type == typeof(System.Object)) return "object";

View File

@ -0,0 +1,160 @@
using System;
using System.Reflection;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using XNode;
namespace XNodeEditor
{
[CustomEditor(typeof(XNode.NodeGraph), true)]
public class NodeGraphInspector : Editor
{
SerializedProperty variablesProp;
List<Type> _knownTypes = new List<Type>();
void OnEnable()
{
variablesProp = serializedObject.FindProperty("variables");
NodeGraph graph = target as NodeGraph;
foreach (var node in graph.nodes)
{
foreach (var port in node.Ports)
{
if (!_knownTypes.Contains(port.ValueType))
_knownTypes.Add(port.ValueType);
}
}
}
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<string> options = new List<string>();
options.Add(typeProp.stringValue);
int idx = 0;
List<string> additionalTypes = new List<string>();
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);
foreach (var type in _knownTypes)
{
if (additionalTypes.Contains(type.AssemblyQualifiedName))
continue;
additionalTypes.Add(type.AssemblyQualifiedName);
}
foreach (var addType in additionalTypes)
{
if (!options.Contains(addType))
options.Add(addType);
}
List<string> prettyOptions = new List<string>();
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();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16edf05454c66b04ba4ebd0bf5b0af6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using XNode;
namespace XNodeEditor
{
[CustomEditor(typeof(Node), true)]
public class NodeInspector : Editor
{
public override void OnInspectorGUI() { /*hides unneeded info*/ }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a079842175cdba54a8c36ad52f983502
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -62,7 +62,6 @@ namespace XNode {
protected void OnEnable() { protected void OnEnable() {
UpdateStaticPorts(); UpdateStaticPorts();
Init();
} }
/// <summary> Update static ports to reflect class fields. This happens automatically on enable. </summary> /// <summary> Update static ports to reflect class fields. This happens automatically on enable. </summary>
@ -71,7 +70,7 @@ namespace XNode {
} }
/// <summary> Initialize node. Called on creation. </summary> /// <summary> Initialize node. Called on creation. </summary>
protected virtual void Init() { name = GetType().Name; } public virtual void Init() { name = GetType().Name; }
/// <summary> Checks all connections for invalid references, and removes them. </summary> /// <summary> Checks all connections for invalid references, and removes them. </summary>
public void VerifyConnections() { public void VerifyConnections() {

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -10,6 +12,9 @@ namespace XNode {
/// <summary> All nodes in the graph. <para/> /// <summary> All nodes in the graph. <para/>
/// See: <see cref="AddNode{T}"/> </summary> /// See: <see cref="AddNode{T}"/> </summary>
[SerializeField] public List<Node> nodes = new List<Node>(); [SerializeField] public List<Node> nodes = new List<Node>();
/// <summary> All variables in the graph. </summary>
[SerializeField] public List<Variable> variables = new List<Variable>();
/// <summary> Add a node to the graph by type </summary> /// <summary> Add a node to the graph by type </summary>
public T AddNode<T>() where T : Node { public T AddNode<T>() where T : Node {
@ -28,6 +33,7 @@ namespace XNode {
#endif #endif
nodes.Add(node); nodes.Add(node);
node.graph = this; node.graph = this;
node.Init();
return node; return node;
} }
@ -44,6 +50,7 @@ namespace XNode {
#endif #endif
nodes.Add(node); nodes.Add(node);
node.graph = this; node.graph = this;
node.Init();
return node; return node;
} }
@ -60,9 +67,10 @@ namespace XNode {
nodes.Remove(node); nodes.Remove(node);
} }
/// <summary> Remove all nodes and connections from the graph </summary> /// <summary> Remove all nodes, connections and variables from the graph </summary>
public void Clear() { public void Clear() {
nodes.Clear(); nodes.Clear();
variables.Clear();
} }
/// <summary> Create a new deep copy of this graph </summary> /// <summary> Create a new deep copy of this graph </summary>
@ -74,6 +82,7 @@ namespace XNode {
Node node = Instantiate(nodes[i]) as Node; Node node = Instantiate(nodes[i]) as Node;
node.graph = graph; node.graph = graph;
graph.nodes[i] = node; graph.nodes[i] = node;
node.Init();
} }
// Redirect all connections // Redirect all connections
@ -85,5 +94,60 @@ namespace XNode {
return graph; return graph;
} }
/// <summary> Add a variable to the graph </summary>
/// <param name="newVariable">the new variable data</param>
/// <returns>the actual id used, avoiding duplicates</returns>
public string AddVariable(Variable newVariable)
{
newVariable.id = GetSafeId(newVariable.id);
newVariable.typeString = GetSafeType(newVariable.typeString);
variables.Add(newVariable);
return newVariable.id;
}
/// <summary> Remove a variable from the graph </summary>
public void RemoveVariable(string id)
{
variables.Remove(GetVariable(id));
}
/// <summary> Get a variable from the graph </summary>
public Variable GetVariable(string id)
{
return variables.Find((Variable v) => v.id == id);
}
/// <summary> Get a duplication safe id </summary>
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();
}
/// <summary> Get a variable safe type </summary>
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;
}
} }
} }

55
Scripts/Variable.cs Normal file
View File

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace XNode
{
[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;
}
}
}

11
Scripts/Variable.cs.meta Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81f7d4c8803ebee4c903b0976f780d95
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: