From 147424ca73d0b29814eb695fd804867ea22a711c Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Mon, 9 Oct 2017 00:29:40 +0200 Subject: [PATCH] Added DisplayValue and GetValue --- Example/ExampleNodeGraph.asset | Bin 4196 -> 5896 bytes Example/Nodes/DisplayValue.cs | 5 +++ Example/Nodes/DisplayValue.cs.meta | 12 ++++++ Example/Nodes/Editor/DisplayValueEditor.cs | 32 ++++++++++++++ .../Nodes/Editor/DisplayValueEditor.cs.meta | 12 ++++++ Example/Nodes/MathNode.cs | 18 +++++++- Scripts/Editor/NodeEditor.cs | 1 - Scripts/Editor/NodeEditorGUI.cs | 2 + Scripts/Node.cs | 40 +++++++++++++++--- Scripts/NodePort.cs | 4 ++ 10 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 Example/Nodes/DisplayValue.cs create mode 100644 Example/Nodes/DisplayValue.cs.meta create mode 100644 Example/Nodes/Editor/DisplayValueEditor.cs create mode 100644 Example/Nodes/Editor/DisplayValueEditor.cs.meta diff --git a/Example/ExampleNodeGraph.asset b/Example/ExampleNodeGraph.asset index 3818860395fba40593b349d133f374883f8c86a7..16e79ec98ced5388a7423c64462f39ff59a7313d 100644 GIT binary patch literal 5896 zcmeI0U2IfE6vxkPw_QGzRxK1o5n3$ZM_~&H0xetmL4neiY8nzlVCi1mZMM6c?Y6cU zV11CJ@qt7^WICdk*nZ$;aULIygeY9qKhr(jYiEYbEja-{cft<+o=F=p*um0f_cBs z&U-gF#X>~9{?AfObML$*F1Mrw^S%!|jDIP4Mvb=uh$odCYc5uhyinPnhkNMHz2r&@ zWjn_9K-s^~<=Xy=to<_bOoo0M_Ggm^$xZuQPu!}w*M7OnEx8I`mY`2R=i*A4YX5$X z|7QOI53fd>{xin&T<$aC`5?G{UY~g5`B0X3bfi=3o5Im_BGojQw&Q)#M7&OVcQr?2 z_U1-3Izs6P8u3Kf?h`e7Q5)KIdgEB~Y5U->nenry>h{k)aN(UR&n}N%x65w+ITrXS zyrE_FmEor`(WUHU`HjQH$Zwo~vvCR#w;MP>xN*4YJsU?(ViP<8=7UadoC3v{W%=aB z(HsYb8b7&lG{?cNI5!T3>s5#ACMY*7HxBkUsCgjFce!~W@F1t~pr9RYSlU@Ym?8J6 z1Fa2R@`WxhG7g*yaDAW^8wXk?xzb|eKwIQ;pKuTEfztjXxaxUL`&BMC?Jp*WSW>L) zIR0}Tv>m_1(cA~+L9`S~vGDpD#|Y;I_o!l;dk><=T<%wKIEX&|d>mJ8f0_{ouCtEA zbR!Nt40Rl)8*$+JYp&xwj6Urz$2C_Rm>0R?TtlwZjPnYY`_v2ZNVdNcSH4-fzKp{g z==z|m$RSQ%y^A*ed6FS< z6^?RVT1oV$)eIq=d?~xHKbDqWlrql@C2d{06v&a*y0YU-d{x`Oe(z}gnwd8{Yk%2s z`9^xnm%sn`!o;D|A2USfp7rBR1dfz^&2JvX|5WqmOBdu$kojXCeU;h0MehBr zw8-V=D<)sMRtHXP$ThBFK zs9Za~yLnEPp1)$&w{PDV+28z9(aws6_1&*%I-Gc`wB*dH`q5*l@7A_=zNo31<4!;5 zAI0luDf&%=q26T7X2G{96-q`phR;NCo|SDU7Hr>+IP=k#^Zcw&x1qS>{WawyW8bX1 z{+UQigI4Vu{}|2Ify!5ob^ItoTQ8d6Rb-CieAiA%aK^Pt{v^6%ar|Y79e?>dxiQ+8 mjD?1}RIZ@kweRzd>reQ`9KU&=*DuG86EClyxyIpkC4T|So1(b@ delta 420 zcmeCsd!it~z`#72fk7aJfq_8~NHa_n5MgB8sA|Kk!w3`t0*B9QAq*f1QUwAaDG+{8 nxgNx2V4VC`L~62`sL^BxQH@bdRv5@n&JfiRfCf4^R6zs)-_c<( diff --git a/Example/Nodes/DisplayValue.cs b/Example/Nodes/DisplayValue.cs new file mode 100644 index 0000000..01a2b0f --- /dev/null +++ b/Example/Nodes/DisplayValue.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class DisplayValue : Node { + [Input] public float value; +} diff --git a/Example/Nodes/DisplayValue.cs.meta b/Example/Nodes/DisplayValue.cs.meta new file mode 100644 index 0000000..aa380ea --- /dev/null +++ b/Example/Nodes/DisplayValue.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 98f6f901f0da53142b79277ea3f42518 +timeCreated: 1507499149 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/Nodes/Editor/DisplayValueEditor.cs b/Example/Nodes/Editor/DisplayValueEditor.cs new file mode 100644 index 0000000..b0f4643 --- /dev/null +++ b/Example/Nodes/Editor/DisplayValueEditor.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +[CustomNodeEditor(typeof(DisplayValue), "Display Value")] +public class DisplayValueEditor : NodeEditor { + + public override void OnNodeGUI(out Dictionary portPositions) { + base.OnNodeGUI(out portPositions); + EditorGUILayout.LabelField("Value: " + GetResult()); + } + + public float GetResult() { + float result = 0f; + NodePort port = target.GetInputByFieldName("value"); + if (port == null) return result; + int connectionCount = port.ConnectionCount; + for (int i = 0; i < connectionCount; i++) { + + NodePort connection = port.GetConnection(i); + if (connection == null) continue; + + object obj = connection.GetValue(); + if (obj == null) continue; + + if (connection.type == typeof(int)) result += (int)obj; + else if (connection.type == typeof(float)) result += (float)obj; + } + return result; + } +} diff --git a/Example/Nodes/Editor/DisplayValueEditor.cs.meta b/Example/Nodes/Editor/DisplayValueEditor.cs.meta new file mode 100644 index 0000000..15cde80 --- /dev/null +++ b/Example/Nodes/Editor/DisplayValueEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 429e0671aa9024e449642837aeadc9c2 +timeCreated: 1507499229 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Example/Nodes/MathNode.cs b/Example/Nodes/MathNode.cs index b9a9d27..32aa322 100644 --- a/Example/Nodes/MathNode.cs +++ b/Example/Nodes/MathNode.cs @@ -2,8 +2,8 @@ [System.Serializable] public class MathNode : Node { - [Input] public float a; - [Input] public float b; + public float a; + public float b; [Output] public float result; public enum MathType { Add, Subtract, Multiply, Divide} public MathType mathType = MathType.Add; @@ -12,6 +12,20 @@ public class MathNode : Node { name = "Math"; } + public override object GetValue(NodePort port) { + switch(port.fieldName) { + case "result": + switch(mathType) { + case MathType.Add: return a + b; + case MathType.Subtract: return a - b; + case MathType.Multiply: return a * b; + case MathType.Divide: return a / b; + } + break; + } + return 0f; + } + public override void OnCreateConnection(NodePort from, NodePort to) { } diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index 25e600a..c2c20d2 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -58,7 +58,6 @@ public class NodeEditor { if (NodeEditorUtilities.HasAttrib(fieldAttribs) || NodeEditorUtilities.HasAttrib(fieldAttribs)) continue; DrawFieldInfoDrawerGUI(fields[i]); } - EditorGUILayout.Space(); } /// Draw node port GUI using automatic layouting. Returns port handle position. diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 9b473ba..cf0c44e 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -167,6 +167,8 @@ public partial class NodeEditorWindow { //Draw node contents Dictionary portHandlePoints; nodeEditor.OnNodeGUI(out portHandlePoints); + EditorGUILayout.Space(); + if (e.type == EventType.Repaint) { foreach (var kvp in portHandlePoints) { Vector2 portHandlePos = kvp.Value; diff --git a/Scripts/Node.cs b/Scripts/Node.cs index 1963d3b..49f62d0 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using System.Linq; using System; /// Base class for all nodes @@ -13,16 +14,18 @@ public abstract class Node : ScriptableObject { /// Input s. It is recommended not to modify these at hand. Instead, see [SerializeField] public List inputs = new List(); /// Output s. It is recommended not to modify these at hand. Instead, see - [SerializeField] public NodePort[] outputs = new NodePort[0]; + [SerializeField] public List outputs = new List(); public int InputCount { get { return inputs.Count; } } - public int OutputCount { get { return outputs.Length; } } + public int OutputCount { get { return outputs.Count; } } protected Node() { CachePorts(); //Cache the ports at creation time so we don't have to use reflection at runtime } protected void OnEnable() { + VerifyConnections(); + CachePorts(); Init(); } @@ -49,6 +52,7 @@ public abstract class Node : ScriptableObject { for (int i = 0; i < OutputCount; i++) { if (outputs[i].fieldName == fieldName) return outputs[i]; } + Debug.LogWarning("No outputs with fieldName '" + fieldName+"'"); return null; } @@ -57,6 +61,12 @@ public abstract class Node : ScriptableObject { for (int i = 0; i < InputCount; i++) { if (inputs[i].fieldName == fieldName) return inputs[i]; } + Debug.LogWarning("No inputs with fieldName '" + fieldName+"'"); + return null; + } + + public virtual object GetValue(NodePort port) { + Debug.LogWarning("No GetValue(NodePort port) override defined for " + GetType()); return null; } @@ -75,7 +85,7 @@ public abstract class Node : ScriptableObject { return -1; } public int GetOutputId(NodePort output) { - for (int i = 0; i < outputs.Length; i++) { + for (int i = 0; i < outputs.Count; i++) { if (output == outputs[i]) return i; } @@ -86,7 +96,7 @@ public abstract class Node : ScriptableObject { for (int i = 0; i < inputs.Count; i++) { inputs[i].ClearConnections(); } - for (int i = 0; i < outputs.Length; i++) { + for (int i = 0; i < outputs.Count; i++) { outputs[i].ClearConnections(); } } @@ -114,6 +124,7 @@ public abstract class Node : ScriptableObject { 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; @@ -122,12 +133,29 @@ public abstract class Node : ScriptableObject { 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], this)); else if (outputAttrib != null) outputPorts.Add(new NodePort(fieldInfo[i], this)); } - inputs = inputPorts; - outputs = outputPorts.ToArray(); + //Remove + for (int i = inputs.Count-1; i >= 0; i--) { + //If input nodeport does not exist, remove it + if (!inputPorts.Any(x => inputs[i].fieldName == x.fieldName)) inputs.RemoveAt(i); + } + for (int i = outputs.Count - 1; i >= 0; i--) { + //If output nodeport does not exist, remove it + if (!outputPorts.Any(x => outputs[i].fieldName == x.fieldName)) outputs.RemoveAt(i); + } + //Add + for (int i = 0; i < inputPorts.Count; i++) { + //If inputports contains a new port, add it + if (!inputs.Any(x => x.fieldName == inputPorts[i].fieldName)) inputs.Add(inputPorts[i]); + } + for (int i = 0; i < outputPorts.Count; i++) { + //If inputports contains a new port, add it + if (!outputs.Any(x => x.fieldName == outputPorts[i].fieldName)) outputs.Add(outputPorts[i]); + } } } diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs index e3d5451..dfef17c 100644 --- a/Scripts/NodePort.cs +++ b/Scripts/NodePort.cs @@ -55,6 +55,10 @@ public class NodePort { } } + public object GetValue() { + return node.GetValue(this); + } + /// Connect this to another /// The to connect to public void Connect(NodePort port) {