diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index 7fdc91e..baf9400 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -473,6 +473,8 @@ namespace XNodeEditor { if (IsDraggingPort) { Gradient gradient = graphEditor.GetNoodleGradient(draggedOutput, null); float thickness = graphEditor.GetNoodleThickness(draggedOutput, null); + NoodlePath path = graphEditor.GetNoodlePath(draggedOutput, null); + NoodleStroke stroke = graphEditor.GetNoodleStroke(draggedOutput, null); Rect fromRect; if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return; @@ -484,7 +486,7 @@ namespace XNodeEditor { if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center); else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition)); - DrawNoodle(gradient, thickness, gridPoints); + DrawNoodle(gradient, path, stroke, thickness, gridPoints); Color bgcol = Color.black; Color frcol = gradient.colorKeys[0].color; diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 76dbb8f..cae1f15 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -117,12 +117,12 @@ namespace XNodeEditor { } /// Draw a bezier from output to input in grid coordinates - public void DrawNoodle(Gradient gradient, float width, List gridPoints) { + public void DrawNoodle(Gradient gradient, NoodlePath path, NoodleStroke stroke, float thickness, List gridPoints) { Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray(); Handles.color = gradient.Evaluate(0f); int length = gridPoints.Count; - switch (NodeEditorPreferences.GetSettings().noodleType) { - case NodeEditorPreferences.NoodleType.Curve: + switch (path) { + case NoodlePath.Curvy: Vector2 outputTangent = Vector2.right; for (int i = 0; i < length - 1; i++) { Vector2 inputTangent = Vector2.left; @@ -150,31 +150,47 @@ namespace XNodeEditor { Vector2 tangent_a = point_a + outputTangent * 50 / zoom; Vector2 tangent_b = point_b + inputTangent * 50 / zoom; // Hover effect. - int division = Mathf.RoundToInt(.1f * dist_ab) + 3; + int division = Mathf.RoundToInt(.2f * dist_ab) + 3; Vector3[] points = Handles.MakeBezierPoints(point_a, point_b, tangent_a, tangent_b, division); + int draw = 0; // Coloring and bezier drawing. for (int j = 0; j < points.Length - 1; j++) { + if (stroke == NoodleStroke.Dashed) { + draw++; + if (draw >= 2) draw = -2; + if (draw < 0) continue; + } + if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate((j + 1f) / points.Length); - Handles.DrawAAPolyLine(width, points[j], points[j + 1]); + Handles.DrawAAPolyLine(thickness, points[j], points[j + 1]); } outputTangent = -inputTangent; } break; - case NodeEditorPreferences.NoodleType.Line: + case NoodlePath.Straight: for (int i = 0; i < length - 1; i++) { Vector2 point_a = windowPoints[i]; Vector2 point_b = windowPoints[i + 1]; // Draws the line with the coloring. Vector2 prev_point = point_a; - for (float j = 0; j < 1; j += 10f / Vector2.Distance(point_a, point_b)) { - Vector2 lerp = Vector2.Lerp(point_a, point_b, j); - if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate(j); - Handles.DrawAAPolyLine(width, prev_point, lerp); + // Approximately one segment per 5 pixels + int segments = (int) Vector2.Distance(point_a, point_b) / 5; + + int draw = 0; + for (int j = 0; j <= segments; j++) { + draw++; + float t = j / (float) segments; + Vector2 lerp = Vector2.Lerp(point_a, point_b, t); + if (draw > 0) { + if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate(t); + Handles.DrawAAPolyLine(thickness, prev_point, lerp); + } prev_point = lerp; + if (stroke == NoodleStroke.Dashed && draw >= 2) draw = -2; } } break; - case NodeEditorPreferences.NoodleType.Angled: + case NoodlePath.Angled: for (int i = 0; i < length - 1; i++) { if (i == length - 1) continue; // Skip last index if (windowPoints[i].x <= windowPoints[i + 1].x - (50 / zoom)) { @@ -184,15 +200,15 @@ namespace XNodeEditor { start_1.x = midpoint; end_1.x = midpoint; if (i == gridPoints.Count - 2) { - Handles.DrawAAPolyLine(width, windowPoints[i], start_1); + Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1); Handles.color = gradient.Evaluate(0.5f); - Handles.DrawAAPolyLine(width, start_1, end_1); + Handles.DrawAAPolyLine(thickness, start_1, end_1); Handles.color = gradient.Evaluate(1f); - Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); + Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]); } else { - Handles.DrawAAPolyLine(width, windowPoints[i], start_1); - Handles.DrawAAPolyLine(width, start_1, end_1); - Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); + Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1); + Handles.DrawAAPolyLine(thickness, start_1, end_1); + Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]); } } else { float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f; @@ -205,21 +221,21 @@ namespace XNodeEditor { start_2.y = midpoint; end_2.y = midpoint; if (i == gridPoints.Count - 2) { - Handles.DrawAAPolyLine(width, windowPoints[i], start_1); + Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1); Handles.color = gradient.Evaluate(0.25f); - Handles.DrawAAPolyLine(width, start_1, start_2); + Handles.DrawAAPolyLine(thickness, start_1, start_2); Handles.color = gradient.Evaluate(0.5f); - Handles.DrawAAPolyLine(width, start_2, end_2); + Handles.DrawAAPolyLine(thickness, start_2, end_2); Handles.color = gradient.Evaluate(0.75f); - Handles.DrawAAPolyLine(width, end_2, end_1); + Handles.DrawAAPolyLine(thickness, end_2, end_1); Handles.color = gradient.Evaluate(1f); - Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); + Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]); } else { - Handles.DrawAAPolyLine(width, windowPoints[i], start_1); - Handles.DrawAAPolyLine(width, start_1, start_2); - Handles.DrawAAPolyLine(width, start_2, end_2); - Handles.DrawAAPolyLine(width, end_2, end_1); - Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); + Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1); + Handles.DrawAAPolyLine(thickness, start_1, start_2); + Handles.DrawAAPolyLine(thickness, start_2, end_2); + Handles.DrawAAPolyLine(thickness, end_2, end_1); + Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]); } } } @@ -250,6 +266,8 @@ namespace XNodeEditor { Gradient noodleGradient = graphEditor.GetNoodleGradient(output, input); float noodleThickness = graphEditor.GetNoodleThickness(output, input); + NoodlePath noodlePath = graphEditor.GetNoodlePath(output, input); + NoodleStroke noodleStroke = graphEditor.GetNoodleStroke(output, input); // Error handling if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return. @@ -263,7 +281,7 @@ namespace XNodeEditor { gridPoints.Add(fromRect.center); gridPoints.AddRange(reroutePoints); gridPoints.Add(toRect.center); - DrawNoodle(noodleGradient, noodleThickness, gridPoints); + DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints); // Loop through reroute points again and draw the points for (int i = 0; i < reroutePoints.Count; i++) { diff --git a/Scripts/Editor/NodeEditorPreferences.cs b/Scripts/Editor/NodeEditorPreferences.cs index b3026b9..642e672 100644 --- a/Scripts/Editor/NodeEditorPreferences.cs +++ b/Scripts/Editor/NodeEditorPreferences.cs @@ -2,10 +2,13 @@ using System.Collections.Generic; using UnityEditor; using UnityEngine; +using UnityEngine.Serialization; namespace XNodeEditor { + public enum NoodlePath { Curvy, Straight, Angled } + public enum NoodleStroke { Full, Dashed } + public static class NodeEditorPreferences { - public enum NoodleType { Curve, Line, Angled } /// The last editor we checked. This should be the one we modify private static XNodeEditor.NodeGraphEditor lastEditor; @@ -37,7 +40,8 @@ namespace XNodeEditor { public bool portTooltips = true; [SerializeField] private string typeColorsData = ""; [NonSerialized] public Dictionary typeColors = new Dictionary(); - public NoodleType noodleType = NoodleType.Curve; + [FormerlySerializedAs("noodleType")] public NoodlePath noodlePath = NoodlePath.Curvy; + public NoodleStroke noodleStroke = NoodleStroke.Full; private Texture2D _gridTexture; public Texture2D gridTexture { @@ -106,7 +110,7 @@ namespace XNodeEditor { private static void PreferencesGUI() { VerifyLoaded(); Settings settings = NodeEditorPreferences.settings[lastKey]; - + if (GUILayout.Button(new GUIContent("Documentation", "https://github.com/Siccity/xNode/wiki"), GUILayout.Width(100))) Application.OpenURL("https://github.com/Siccity/xNode/wiki"); EditorGUILayout.Space(); @@ -151,7 +155,8 @@ namespace XNodeEditor { //Label EditorGUILayout.LabelField("Node", EditorStyles.boldLabel); settings.highlightColor = EditorGUILayout.ColorField("Selection", settings.highlightColor); - settings.noodleType = (NoodleType) EditorGUILayout.EnumPopup("Noodle type", (Enum) settings.noodleType); + settings.noodlePath = (NoodlePath) EditorGUILayout.EnumPopup("Noodle path", (Enum) settings.noodlePath); + settings.noodleStroke = (NoodleStroke) EditorGUILayout.EnumPopup("Noodle stroke", (Enum) settings.noodleStroke); settings.portTooltips = EditorGUILayout.Toggle("Port Tooltips", settings.portTooltips); settings.dragToCreate = EditorGUILayout.Toggle(new GUIContent("Drag to Create", "Drag a port connection anywhere on the grid to create and connect a node"), settings.dragToCreate); if (GUI.changed) { diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index 0829e4d..bc6e14c 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -101,6 +101,14 @@ namespace XNodeEditor { return 5f; } + public virtual NoodlePath GetNoodlePath(XNode.NodePort output, XNode.NodePort input) { + return NodeEditorPreferences.GetSettings().noodlePath; + } + + public virtual NoodleStroke GetNoodleStroke(XNode.NodePort output, XNode.NodePort input) { + return NodeEditorPreferences.GetSettings().noodleStroke; + } + /// Returned color is used to color ports public virtual Color GetPortColor(XNode.NodePort port) { return GetTypeColor(port.ValueType);