mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-20 01:06:01 +08:00
Started work on NodeGraphExample
This commit is contained in:
parent
63808eb6a2
commit
f8a0bb8f7c
9
Examples/NodeToy.meta
Normal file
9
Examples/NodeToy.meta
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52f863b8b4fc21f47b2af1dd63a719ff
|
||||
folderAsset: yes
|
||||
timeCreated: 1506460802
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Examples/NodeToy/MathToyNodeGraph.cs
Normal file
9
Examples/NodeToy/MathToyNodeGraph.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary> Defines an example nodegraph. </summary>
|
||||
[CreateAssetMenu(fileName = "NodeGraphExample", menuName = "Node Graph/Example")]
|
||||
public class NodeGraphExample : NodeGraph {
|
||||
|
||||
}
|
||||
12
Examples/NodeToy/MathToyNodeGraph.cs.meta
Normal file
12
Examples/NodeToy/MathToyNodeGraph.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6399826e2c44b447b32a3ed06646162
|
||||
timeCreated: 1506460823
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Examples/NodeToy/NodeGraphExample.asset
Normal file
BIN
Examples/NodeToy/NodeGraphExample.asset
Normal file
Binary file not shown.
9
Examples/NodeToy/NodeGraphExample.asset.meta
Normal file
9
Examples/NodeToy/NodeGraphExample.asset.meta
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84fbc8acdc9656941b529a16e8bbe318
|
||||
timeCreated: 1506462197
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ public class NodeEditor {
|
||||
public virtual void OnNodeGUI() {
|
||||
portRects.Clear();
|
||||
DrawDefaultNodePortsGUI();
|
||||
DrawDefaultNodeBody();
|
||||
DrawDefaultNodeBodyGUI();
|
||||
}
|
||||
|
||||
/// <summary> Draws standard editors for all fields marked with <see cref="Node.InputAttribute"/> or <see cref="Node.OutputAttribute"/> </summary>
|
||||
@ -42,75 +42,12 @@ public class NodeEditor {
|
||||
}
|
||||
|
||||
/// <summary> Draws standard field editors for all public fields </summary>
|
||||
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<Node.InputAttribute>(fieldAttribs) || NodeEditorUtilities.HasAttrib<Node.OutputAttribute>(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)]
|
||||
|
||||
@ -18,9 +18,9 @@ public partial class NodeEditorWindow : EditorWindow {
|
||||
private float _zoom = 1;
|
||||
|
||||
partial void OnEnable();
|
||||
|
||||
[MenuItem("Window/UNEC")]
|
||||
static NodeEditorWindow Init() {
|
||||
/// <summary> Create editor window </summary>
|
||||
//[MenuItem("Window/UNEC")]
|
||||
public static NodeEditorWindow Init() {
|
||||
NodeEditorWindow w = CreateInstance<NodeEditorWindow>();
|
||||
w.titleContent = new GUIContent("UNEC");
|
||||
w.wantsMouseMove = true;
|
||||
|
||||
@ -26,9 +26,11 @@ public abstract class Node {
|
||||
}
|
||||
|
||||
/// <summary> Initialize node. Called on creation. </summary>
|
||||
protected virtual void Init() {
|
||||
protected virtual void Init() { }
|
||||
|
||||
}
|
||||
/// <summary> Called whenever a connection is being made between two <see cref="NodePort"/>s</summary>
|
||||
/// <param name="from">Output</param> <param name="to">Input</param>
|
||||
public virtual void OnCreateConnection(NodePort from, NodePort to) { }
|
||||
|
||||
public int GetInputId(NodePort input) {
|
||||
for (int i = 0; i < inputs.Length; i++) {
|
||||
|
||||
@ -13,26 +13,11 @@ public abstract class NodeGraph : ScriptableObject {
|
||||
[SerializeField] public string[] s_nodes;
|
||||
|
||||
public T AddNode<T>() 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);
|
||||
}
|
||||
|
||||
/// <summary> Remove all nodes and connections from the graph </summary>
|
||||
public void Clear() {
|
||||
nodes.Clear();
|
||||
}
|
||||
|
||||
private class NodeTyper {
|
||||
public string nodeType = "Node";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,8 @@ public class NodePort {
|
||||
_direction = direction;
|
||||
}
|
||||
|
||||
/// <summary> Connect this <see cref="NodePort"/> to another </summary>
|
||||
/// <param name="port">The <see cref="NodePort"/> to connect to</param>
|
||||
public void Connect(NodePort port) {
|
||||
if (connections == null) connections = new List<NodePort>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user