mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-20 09:16: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 {
|
public class MathNode : Node {
|
||||||
[Input] public float a;
|
[Input] public float a;
|
||||||
[Input] public float b;
|
[Input] public float b;
|
||||||
@ -9,4 +11,8 @@ public class MathNode : Node {
|
|||||||
protected override void Init() {
|
protected override void Init() {
|
||||||
name = "Math";
|
name = "Math";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnCreateConnection(NodePort from, NodePort to) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class NodeEditor {
|
|||||||
public virtual void OnNodeGUI() {
|
public virtual void OnNodeGUI() {
|
||||||
portRects.Clear();
|
portRects.Clear();
|
||||||
DrawDefaultNodePortsGUI();
|
DrawDefaultNodePortsGUI();
|
||||||
DrawDefaultNodeBody();
|
DrawDefaultNodeBodyGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draws standard editors for all fields marked with <see cref="Node.InputAttribute"/> or <see cref="Node.OutputAttribute"/> </summary>
|
/// <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>
|
/// <summary> Draws standard field editors for all public fields </summary>
|
||||||
protected void DrawDefaultNodeBody() {
|
protected void DrawDefaultNodeBodyGUI() {
|
||||||
FieldInfo[] fields = GetInspectorFields(target);
|
FieldInfo[] fields = GetInspectorFields(target);
|
||||||
for (int i = 0; i < fields.Length; i++) {
|
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);
|
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;
|
if (NodeEditorUtilities.HasAttrib<Node.InputAttribute>(fieldAttribs) || NodeEditorUtilities.HasAttrib<Node.OutputAttribute>(fieldAttribs)) continue;
|
||||||
|
DrawFieldInfoDrawerGUI(fields[i]);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
}
|
}
|
||||||
@ -145,6 +82,72 @@ public class NodeEditor {
|
|||||||
private static FieldInfo[] GetInspectorFields(Node node) {
|
private static FieldInfo[] GetInspectorFields(Node node) {
|
||||||
return node.GetType().GetFields().Where(f => f.IsPublic || f.GetCustomAttributes(typeof(SerializeField),false) != null).ToArray();
|
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)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
|||||||
@ -18,9 +18,9 @@ public partial class NodeEditorWindow : EditorWindow {
|
|||||||
private float _zoom = 1;
|
private float _zoom = 1;
|
||||||
|
|
||||||
partial void OnEnable();
|
partial void OnEnable();
|
||||||
|
/// <summary> Create editor window </summary>
|
||||||
[MenuItem("Window/UNEC")]
|
//[MenuItem("Window/UNEC")]
|
||||||
static NodeEditorWindow Init() {
|
public static NodeEditorWindow Init() {
|
||||||
NodeEditorWindow w = CreateInstance<NodeEditorWindow>();
|
NodeEditorWindow w = CreateInstance<NodeEditorWindow>();
|
||||||
w.titleContent = new GUIContent("UNEC");
|
w.titleContent = new GUIContent("UNEC");
|
||||||
w.wantsMouseMove = true;
|
w.wantsMouseMove = true;
|
||||||
|
|||||||
@ -26,9 +26,11 @@ public abstract class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Initialize node. Called on creation. </summary>
|
/// <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) {
|
public int GetInputId(NodePort input) {
|
||||||
for (int i = 0; i < inputs.Length; i++) {
|
for (int i = 0; i < inputs.Length; i++) {
|
||||||
|
|||||||
@ -13,26 +13,11 @@ public abstract class NodeGraph : ScriptableObject {
|
|||||||
[SerializeField] public string[] s_nodes;
|
[SerializeField] public string[] s_nodes;
|
||||||
|
|
||||||
public T AddNode<T>() where T : Node {
|
public T AddNode<T>() where T : Node {
|
||||||
T node = default(T);
|
return AddNode(typeof(T)) as T;
|
||||||
return AddNode(node) as T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node AddNode(Type type) {
|
public virtual Node AddNode(Type type) {
|
||||||
Node node = (Node)Activator.CreateInstance(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);
|
nodes.Add(node);
|
||||||
node.graph = this;
|
node.graph = this;
|
||||||
return node;
|
return node;
|
||||||
@ -45,12 +30,9 @@ public abstract class NodeGraph : ScriptableObject {
|
|||||||
nodes.Remove(node);
|
nodes.Remove(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Remove all nodes and connections from the graph </summary>
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
nodes.Clear();
|
nodes.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NodeTyper {
|
|
||||||
public string nodeType = "Node";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,8 @@ public class NodePort {
|
|||||||
_direction = direction;
|
_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) {
|
public void Connect(NodePort port) {
|
||||||
if (connections == null) connections = new List<NodePort>();
|
if (connections == null) connections = new List<NodePort>();
|
||||||
if (port == null) { Debug.LogWarning("Cannot connect to null port"); return; }
|
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; }
|
if (direction == port.direction) { Debug.LogWarning("Cannot connect two " + (direction == IO.Input ? "input" : "output") + " connections"); return; }
|
||||||
connections.Add(port);
|
connections.Add(port);
|
||||||
port.connections.Add(this);
|
port.connections.Add(this);
|
||||||
|
node.OnCreateConnection(this, port);
|
||||||
|
port.node.OnCreateConnection(this, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodePort GetConnection(int i) {
|
public NodePort GetConnection(int i) {
|
||||||
@ -66,10 +70,4 @@ public class NodePort {
|
|||||||
}
|
}
|
||||||
connections.Clear();
|
connections.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
private class PortID {
|
|
||||||
public int nodeID;
|
|
||||||
public int portID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user