mirror of
https://github.com/Siccity/xNode.git
synced 2026-02-09 08:38:44 +08:00
Streamlined creation of custom node ports
Instead of initializing port arrays in Init();, ports are now defined by attributes on public fields
This commit is contained in:
parent
97bbc236be
commit
59085db16a
@ -3,6 +3,8 @@
|
|||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class BaseNode : Node {
|
public class BaseNode : Node {
|
||||||
|
|
||||||
|
[Input] public string input;
|
||||||
|
[Output] public string output;
|
||||||
public bool concat;
|
public bool concat;
|
||||||
[TextArea]
|
[TextArea]
|
||||||
public string SomeString;
|
public string SomeString;
|
||||||
@ -10,11 +12,4 @@ public class BaseNode : Node {
|
|||||||
public Color col;
|
public Color col;
|
||||||
public AnimationCurve anim;
|
public AnimationCurve anim;
|
||||||
public Vector3 vec;
|
public Vector3 vec;
|
||||||
protected override void Init() {
|
|
||||||
inputs = new NodePort[2];
|
|
||||||
inputs[0] = CreateNodeInput("IntInput", typeof(int));
|
|
||||||
inputs[1] = CreateNodeInput("StringInput", typeof(string));
|
|
||||||
outputs = new NodePort[1];
|
|
||||||
outputs[0] = CreateNodeOutput("StringOutput", typeof(string));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,25 +2,11 @@
|
|||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class MathNode : Node {
|
public class MathNode : Node {
|
||||||
|
[Input] public float a;
|
||||||
|
[Input] public float b;
|
||||||
|
[Output] public float result;
|
||||||
public enum ValueType { Float, Int }
|
public enum ValueType { Float, Int }
|
||||||
public enum MathType { Add, Subtract, Multiply, Divide}
|
public enum MathType { Add, Subtract, Multiply, Divide}
|
||||||
public ValueType valueType = ValueType.Float;
|
public ValueType valueType = ValueType.Float;
|
||||||
public MathType mathType = MathType.Add;
|
public MathType mathType = MathType.Add;
|
||||||
|
|
||||||
protected override void Init() {
|
|
||||||
inputs = new NodePort[2];
|
|
||||||
inputs[0] = CreateNodeInput("A", typeof(float));
|
|
||||||
inputs[1] = CreateNodeInput("B", typeof(float));
|
|
||||||
outputs = new NodePort[1];
|
|
||||||
outputs[0] = CreateNodeOutput("Result", typeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnValidate() {
|
|
||||||
System.Type type = typeof(int);
|
|
||||||
if (valueType == ValueType.Float) type = typeof(float);
|
|
||||||
inputs[0].type = type;
|
|
||||||
inputs[1].type = type;
|
|
||||||
outputs[0].type = type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,11 +14,11 @@ public class NodeEditor {
|
|||||||
public virtual void OnNodeGUI() {
|
public virtual void OnNodeGUI() {
|
||||||
portRects.Clear();
|
portRects.Clear();
|
||||||
DrawNodePortsGUI();
|
DrawNodePortsGUI();
|
||||||
DrawDefaultNodeGUI();
|
DrawDefaultNodeBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draws standard field editors for all public fields </summary>
|
/// <summary> Draws standard field editors for all public fields </summary>
|
||||||
protected void DrawDefaultNodeGUI() {
|
protected void DrawDefaultNodeBody() {
|
||||||
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;
|
Type fieldType = fields[i].FieldType;
|
||||||
@ -31,6 +31,9 @@ public class NodeEditor {
|
|||||||
EditorGUILayout.LabelField(headerAttrib.header);
|
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();
|
EditorGUI.BeginChangeCheck();
|
||||||
if (fieldType == typeof(int)) {
|
if (fieldType == typeof(int)) {
|
||||||
fieldValue = EditorGUILayout.IntField(fieldName, (int)fieldValue);
|
fieldValue = EditorGUILayout.IntField(fieldName, (int)fieldValue);
|
||||||
|
|||||||
@ -23,6 +23,15 @@ public static class NodeEditorUtilities {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool HasAttrib<T>(object[] attribs) where T : Attribute {
|
||||||
|
for (int i = 0; i < attribs.Length; i++) {
|
||||||
|
if (attribs[i].GetType() == typeof(T)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Return color based on type </summary>
|
/// <summary> Return color based on type </summary>
|
||||||
public static Color GetTypeColor(Type type) {
|
public static Color GetTypeColor(Type type) {
|
||||||
UnityEngine.Random.InitState(type.Name.GetHashCode());
|
UnityEngine.Random.InitState(type.Name.GetHashCode());
|
||||||
|
|||||||
@ -14,18 +14,21 @@ public abstract class Node {
|
|||||||
[SerializeField] private string nodeType;
|
[SerializeField] private string nodeType;
|
||||||
|
|
||||||
[SerializeField] public Rect position = new Rect(0,0,200,200);
|
[SerializeField] public Rect position = new Rect(0,0,200,200);
|
||||||
[SerializeField] protected NodePort[] inputs = new NodePort[0];
|
[SerializeField] private NodePort[] inputs = new NodePort[0];
|
||||||
[SerializeField] protected NodePort[] outputs = new NodePort[0];
|
[SerializeField] private NodePort[] outputs = new NodePort[0];
|
||||||
|
|
||||||
public int InputCount { get { return inputs.Length; } }
|
public int InputCount { get { return inputs.Length; } }
|
||||||
public int OutputCount { get { return outputs.Length; } }
|
public int OutputCount { get { return outputs.Length; } }
|
||||||
|
|
||||||
protected Node() {
|
protected Node() {
|
||||||
nodeType = GetType().ToString();
|
nodeType = GetType().ToString();
|
||||||
|
CachePorts();
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void Init();
|
protected virtual void Init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
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++) {
|
||||||
@ -75,4 +78,40 @@ public abstract class Node {
|
|||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
||||||
return JsonUtility.ToJson(this).GetHashCode();
|
return JsonUtility.ToJson(this).GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||||
|
public class InputAttribute : Attribute {
|
||||||
|
public InputAttribute() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||||
|
public class OutputAttribute : Attribute {
|
||||||
|
public OutputAttribute() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Use reflection to find all fields with <see cref="InputAttribute"/> or <see cref="OutputAttribute"/>, and write to <see cref="inputs"/> and <see cref="outputs"/> </summary>
|
||||||
|
private void CachePorts() {
|
||||||
|
List<NodePort> inputPorts = new List<NodePort>();
|
||||||
|
List<NodePort> outputPorts = new List<NodePort>();
|
||||||
|
|
||||||
|
System.Reflection.FieldInfo[] fieldInfo = GetType().GetFields();
|
||||||
|
for (int i = 0; i < fieldInfo.Length; i++) {
|
||||||
|
//Get InputAttribute and OutputAttribute
|
||||||
|
object[] attribs = fieldInfo[i].GetCustomAttributes(false);
|
||||||
|
InputAttribute inputAttrib = null;
|
||||||
|
OutputAttribute outputAttrib = null;
|
||||||
|
for (int k = 0; k < attribs.Length; k++) {
|
||||||
|
if (attribs[k] is InputAttribute) inputAttrib = attribs[k] as InputAttribute;
|
||||||
|
else if (attribs[k] is OutputAttribute) outputAttrib = attribs[k] as OutputAttribute;
|
||||||
|
}
|
||||||
|
if (inputAttrib != null && outputAttrib != null) Debug.LogError("Field " + fieldInfo + " cannot be both input and output.");
|
||||||
|
else if (inputAttrib != null) inputPorts.Add(new NodePort(fieldInfo[i].Name, fieldInfo[i].FieldType, this, NodePort.IO.Input));
|
||||||
|
else if (outputAttrib != null) outputPorts.Add(new NodePort(fieldInfo[i].Name, fieldInfo[i].FieldType, this, NodePort.IO.Output));
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs = inputPorts.ToArray();
|
||||||
|
outputs = outputPorts.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user