From 07d0122b7263799fdc41bb540194d91974e6ec26 Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Fri, 11 Nov 2016 22:54:25 -0800 Subject: [PATCH 1/7] Updated curves, connection points, and grid background -Replaced GLDraw calls with Handles calls for connection curves -Replaced GUI.Label calls with GUI.DrawTexture calls for connection points -Replaced GUI.DrawTexture with native graph background draw call -Removed GLDraw.cs --- .../Textures/connection_point.png | Bin 0 -> 982 bytes .../Textures/connection_point.png.meta | 59 ++++ .../Fungus/Scripts/Editor/FlowchartWindow.cs | 105 +++++-- .../Editor/FungusEditorResourcesGenerated.cs | 2 + Assets/Fungus/Scripts/Editor/GLDraw.cs | 292 ------------------ Assets/Fungus/Scripts/Editor/GLDraw.cs.meta | 8 - 6 files changed, 132 insertions(+), 334 deletions(-) create mode 100644 Assets/Fungus/EditorResources/Textures/connection_point.png create mode 100644 Assets/Fungus/EditorResources/Textures/connection_point.png.meta delete mode 100644 Assets/Fungus/Scripts/Editor/GLDraw.cs delete mode 100644 Assets/Fungus/Scripts/Editor/GLDraw.cs.meta diff --git a/Assets/Fungus/EditorResources/Textures/connection_point.png b/Assets/Fungus/EditorResources/Textures/connection_point.png new file mode 100644 index 0000000000000000000000000000000000000000..5a6719e7e1adf90939117b0a0c5403c854f02fcd GIT binary patch literal 982 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4(FKV3f`bi71Ki^|4CM&(%vz$xlkv ztH>-n*TA>HIW;5GqpB!1xXLdi zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}6yY17;GAES zs$i;Ts%M~N$E9FXl#*r@k>g7FXt#Bv$C=6)S^`fSBQuTAW;zSx}OhpQivaGchT@w8U0PNgrg1KGYVVbM@iw z1#;j%PR#>)vk2%PDX-P9fWg$7>FgX(9OUk#;OXjYW@u?t+)-)8P3t=JN+%w|if>;^#X5r>ow7U%xfyh%c|q*+Y+K^Qt zl0NkOP@S`$#-9~mB3k1`)la_(vD|wsNk!$2=r`4Di?G8{r%rJ2bC;)Is(kz1?v?7= zk8dtDU0Pb6D3sWxV3#&Syh+uQ%FHoko?v}1|h^`lue z>o^wYFA`rB_1&%4RL!N$k8(EX3?Yx{34>Bh`6=7AC?XMsm#F#`j)FbFd;%$g$s6ujW+;uvDlyY{kS z-XRBp)`#b#mwvFkwCte(qpGc?i$~C|g4QX_6Pyn)Dm`+(u;i(XN5Dc6xdWRRPV((H zIh%F=^0_yAe7cXnd?u$a;c`$bD{kt~U6uCP9K!cLbnf0(xWTzGGW6N+#f}~O4fiPI zY(7#9u)^l9K^q7bwtLolbM%lCGH$~5U=vJ=}T&df_a#d9AnJMK9m{#C%$VBUv^Ro2max@9hSJZ_A5yYX{j+?L0G Y*p<31`14sCZ-9L4>FVdQ&MBb@0GeZ*{{R30 literal 0 HcmV?d00001 diff --git a/Assets/Fungus/EditorResources/Textures/connection_point.png.meta b/Assets/Fungus/EditorResources/Textures/connection_point.png.meta new file mode 100644 index 00000000..51982bb8 --- /dev/null +++ b/Assets/Fungus/EditorResources/Textures/connection_point.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: f08a4c27d7efe4aa6a35348a4e8aec8f +timeCreated: 1478932274 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs index c11ac1bd..2ceac788 100644 --- a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs +++ b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs @@ -34,11 +34,15 @@ namespace Fungus.EditorUtils protected int forceRepaintCount; protected Texture2D addTexture; + protected Texture2D connectionPointTexture; protected Rect selectionBox; protected Vector2 startSelectionBoxPosition = -Vector2.one; protected List mouseDownSelectionState = new List(); + protected Color gridLineColor = Color.black; + protected readonly Color connectionColor = new Color(0.65f, 0.65f, 0.65f, 1.0f); + // Context Click occurs on MouseDown which interferes with panning // Track right click positions manually to show menus on MouseUp protected Vector2 rightClickDown = -Vector2.one; @@ -66,6 +70,8 @@ namespace Fungus.EditorUtils nodeStyle.wordWrap = true; addTexture = FungusEditorResources.AddSmall; + connectionPointTexture = FungusEditorResources.ConnectionPoint; + gridLineColor.a = EditorGUIUtility.isProSkin ? 0.5f : 0.25f; } protected virtual void OnInspectorUpdate() @@ -299,6 +305,13 @@ namespace Fungus.EditorUtils flowchart.ScrollViewRect = newRect; } + // Draw background color / drop shadow + if (Event.current.type == EventType.Repaint) + { + UnityEditor.Graphs.Styles.graphBackground.Draw( + new Rect(0, 17, position.width, position.height - 17), false, false, false, false + ); + } // Calc rect for script view Rect scriptViewRect = new Rect(0, 0, this.position.width / flowchart.Zoom, this.position.height / flowchart.Zoom); @@ -320,10 +333,11 @@ namespace Fungus.EditorUtils EditorZoomArea.Begin(flowchart.Zoom, scriptViewRect); - DrawGrid(flowchart); + if (Event.current.type == EventType.Repaint) + { + DrawGrid(flowchart); + } - GLDraw.BeginGroup(scriptViewRect); - // The center of the Flowchart depends on the block positions and window dimensions, so we calculate it // here in the FlowchartWindow class and store it on the Flowchart object for use later. if (flowchart != null && blocks.Length > 0) @@ -485,8 +499,6 @@ namespace Fungus.EditorUtils PanAndZoom(flowchart); - GLDraw.EndGroup(); - EditorZoomArea.End(); // Handle right click up outside of EditorZoomArea to avoid strange offsets @@ -720,26 +732,14 @@ namespace Fungus.EditorUtils float width = this.position.width / flowchart.Zoom; float height = this.position.height / flowchart.Zoom; - // Match background color of scene view - if (EditorGUIUtility.isProSkin) - { - GUI.color = new Color32(71, 71, 71, 255); - } - else - { - GUI.color = new Color32(86, 86, 86, 255); - } - GUI.DrawTexture( new Rect(0,0, width, height), EditorGUIUtility.whiteTexture ); - - GUI.color = Color.white; - Color color = new Color32(96, 96, 96, 255); + Handles.color = gridLineColor; float gridSize = 128f; float x = flowchart.ScrollPos.x % gridSize; while (x < width) { - GLDraw.DrawLine(new Vector2(x, 0), new Vector2(x, height), color, 1f); + Handles.DrawLine(new Vector2(x, 0), new Vector2(x, height)); x += gridSize; } @@ -748,10 +748,12 @@ namespace Fungus.EditorUtils { if (y >= 0) { - GLDraw.DrawLine(new Vector2(0, y), new Vector2(width, y), color, 1f); + Handles.DrawLine(new Vector2(0, y), new Vector2(width, y)); } y += gridSize; } + + Handles.color = Color.white; } protected virtual void SelectBlock(Flowchart flowchart, Block block) @@ -990,17 +992,17 @@ namespace Fungus.EditorUtils protected virtual void DrawRectConnection(Rect rectA, Rect rectB, bool highlight) { Vector2[] pointsA = new Vector2[] { - new Vector2(rectA.xMin + 5, rectA.center.y), - new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin + 2), - new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax - 2), - new Vector2(rectA.xMax - 5, rectA.center.y) + new Vector2(rectA.xMin, rectA.center.y), + new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin), + new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax), + new Vector2(rectA.xMax, rectA.center.y) }; Vector2[] pointsB = new Vector2[] { - new Vector2(rectB.xMin + 5, rectB.center.y), - new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin + 2), - new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax - 2), - new Vector2(rectB.xMax - 5, rectB.center.y) + new Vector2(rectB.xMin, rectB.center.y), + new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin), + new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax), + new Vector2(rectB.xMax, rectB.center.y) }; Vector2 pointA = Vector2.zero; @@ -1021,19 +1023,54 @@ namespace Fungus.EditorUtils } } - Color color = Color.grey; + Color color = connectionColor; if (highlight) { color = Color.green; } - GLDraw.DrawConnectingCurve(pointA, pointB, color, 1.025f); + Handles.color = color; + + // Place control based on distance between points + // Weight the min component more so things don't get overly curvy + var diff = pointA - pointB; + diff.x = Mathf.Abs(diff.x); + diff.y = Mathf.Abs(diff.y); + var min = Mathf.Min(diff.x, diff.y); + var max = Mathf.Max(diff.x, diff.y); + var mod = min * 0.75f + max * 0.25f; + + // Draw bezier curve connecting blocks + var directionA = (rectA.center - pointA).normalized; + var directionB = (rectB.center - pointB).normalized; + var controlA = pointA - directionA * mod * 0.67f; + var controlB = pointB - directionB * mod * 0.67f; + Handles.DrawBezier(pointA, pointB, controlA, controlB, color, null, 3f); + + // Draw arrow on curve + var point = GetPointOnCurve(pointA, controlA, pointB, controlB, 0.7f); + var direction = (GetPointOnCurve(pointA, controlA, pointB, controlB, 0.6f) - point).normalized; + var perp = new Vector2(direction.y, -direction.x); + Handles.DrawAAConvexPolygon( + point, point + direction * 10 + perp * 5, point + direction * 10 - perp * 5 + ); + + var connectionPointA = pointA + directionA * 4f; + var connectionRectA = new Rect(connectionPointA.x - 4f, connectionPointA.y - 4f, 8f, 8f); + var connectionPointB = pointB + directionB * 4f; + var connectionRectB = new Rect(connectionPointB.x - 4f, connectionPointB.y - 4f, 8f, 8f); - Rect dotARect = new Rect(pointA.x - 5, pointA.y - 5, 10, 10); - GUI.Label(dotARect, "", new GUIStyle("U2D.dragDotActive")); + GUI.DrawTexture(connectionRectA, connectionPointTexture, ScaleMode.ScaleToFit); + GUI.DrawTexture(connectionRectB, connectionPointTexture, ScaleMode.ScaleToFit); - Rect dotBRect = new Rect(pointB.x - 5, pointB.y - 5, 10, 10); - GUI.Label(dotBRect, "", new GUIStyle("U2D.dragDotActive")); + Handles.color = Color.white; + } + + private static Vector2 GetPointOnCurve(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) + { + float rt = 1 - t; + float rtt = rt * t; + return rt * rt * rt * s + 3 * rt * rtt * st + 3 * rtt * t * et + t * t * t * e; } public static void DeleteBlocks(object obj) diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs index e2eab920..c7ea8069 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs @@ -17,6 +17,7 @@ namespace Fungus.EditorUtils "choice_node_off", "choice_node_on", "command_background", + "connection_point", "event_node_off", "event_node_on", "play_big", @@ -34,6 +35,7 @@ namespace Fungus.EditorUtils public static Texture2D ChoiceNodeOff { get { return GetTexture("choice_node_off"); } } public static Texture2D ChoiceNodeOn { get { return GetTexture("choice_node_on"); } } public static Texture2D CommandBackground { get { return GetTexture("command_background"); } } + public static Texture2D ConnectionPoint { get { return GetTexture("connection_point"); } } public static Texture2D EventNodeOff { get { return GetTexture("event_node_off"); } } public static Texture2D EventNodeOn { get { return GetTexture("event_node_on"); } } public static Texture2D PlayBig { get { return GetTexture("play_big"); } } diff --git a/Assets/Fungus/Scripts/Editor/GLDraw.cs b/Assets/Fungus/Scripts/Editor/GLDraw.cs deleted file mode 100644 index 9ef5b222..00000000 --- a/Assets/Fungus/Scripts/Editor/GLDraw.cs +++ /dev/null @@ -1,292 +0,0 @@ -// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus). -// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) - -using UnityEngine; - -namespace Fungus.EditorUtils -{ - /// - /// Clipping code: http://forum.unity3d.com/threads/17066-How-to-draw-a-GUI-2D-quot-line-quot?p=230386#post230386 - /// Thick line drawing code: http://unifycommunity.com/wiki/index.php?title=VectorLine - /// Credit: "http://cs-people.bu.edu/jalon/cs480/Oct11Lab/clip.c" - /// - public class GLDraw - { - protected static bool clippingEnabled; - protected static Rect clippingBounds; - public static Material lineMaterial = null; - - protected static bool clip_test(float p, float q, ref float u1, ref float u2) - { - float r; - bool retval = true; - - if (p < 0.0) - { - r = q / p; - if (r > u2) - retval = false; - else if (r > u1) - u1 = r; - } - else if (p > 0.0) - { - r = q / p; - if (r < u1) - retval = false; - else if (r < u2) - u2 = r; - } - else if (q < 0.0) - retval = false; - - return retval; - } - - public static bool segment_rect_intersection(Rect bounds, ref Vector2 p1, ref Vector2 p2) - { - float u1 = 0.0f, u2 = 1.0f, dx = p2.x - p1.x, dy; - - if (clip_test(-dx, p1.x - bounds.xMin, ref u1, ref u2)) - { - if (clip_test(dx, bounds.xMax - p1.x, ref u1, ref u2)) - { - dy = p2.y - p1.y; - if (clip_test(-dy, p1.y - bounds.yMin, ref u1, ref u2)) - { - if (clip_test(dy, bounds.yMax - p1.y, ref u1, ref u2)) - { - if (u2 < 1.0) - { - p2.x = p1.x + u2 * dx; - p2.y = p1.y + u2 * dy; - } - - if (u1 > 0.0) - { - p1.x += u1 * dx; - p1.y += u1 * dy; - } - return true; - } - } - } - } - return false; - } - - public static void BeginGroup(Rect position) - { - clippingEnabled = true; - clippingBounds = new Rect(0, 0, position.width, position.height); - GUI.BeginGroup(position); - } - - public static void EndGroup() - { - GUI.EndGroup(); - clippingBounds = new Rect(0, 0, Screen.width, Screen.height); - clippingEnabled = false; - } - - public static Vector2 BeginScrollView(Rect position, Vector2 scrollPos, Rect viewRect, Rect clipRect) - { - clippingEnabled = true; - clippingBounds = clipRect; - return GUI.BeginScrollView(position, scrollPos, viewRect, GUIStyle.none, GUIStyle.none); - } - - public static void EndScrollView() - { - GUI.EndScrollView(); - clippingBounds = new Rect(0, 0, Screen.width, Screen.height); - clippingEnabled = false; - } - - public static void CreateMaterial() - { - if (lineMaterial != null) - return; - - lineMaterial = Resources.Load("GLLineDraw", typeof(Material)) as Material; - } - - public static void DrawLine(Vector2 start, Vector2 end, Color color, float width) - { - if (Event.current == null) - return; - if (Event.current.type != EventType.repaint) - return; - - if (clippingEnabled) - if (!segment_rect_intersection(clippingBounds, ref start, ref end)) - return; - - CreateMaterial(); - - lineMaterial.SetPass(0); - - Vector3 startPt; - Vector3 endPt; - - if (width == 1) - { - GL.Begin(GL.LINES); - GL.Color(color); - startPt = new Vector3(start.x, start.y, 0); - endPt = new Vector3(end.x, end.y, 0); - GL.Vertex(startPt); - GL.Vertex(endPt); - } - else - { - GL.Begin(GL.QUADS); - GL.Color(color); - startPt = new Vector3(end.y, start.x, 0); - endPt = new Vector3(start.y, end.x, 0); - Vector3 perpendicular = (startPt - endPt).normalized * width; - Vector3 v1 = new Vector3(start.x, start.y, 0); - Vector3 v2 = new Vector3(end.x, end.y, 0); - GL.Vertex(v1 - perpendicular); - GL.Vertex(v1 + perpendicular); - GL.Vertex(v2 + perpendicular); - GL.Vertex(v2 - perpendicular); - } - GL.End(); - } - - public static void DrawRect(Rect rect, Color color) - { - if (Event.current == null) - return; - if (Event.current.type != EventType.repaint) - return; - - CreateMaterial(); - // set the current material - lineMaterial.SetPass( 0 ); - GL.Begin( GL.QUADS ); - GL.Color( color ); - GL.Vertex3( rect.xMin, rect.yMin, 0 ); - GL.Vertex3( rect.xMax, rect.yMin, 0 ); - GL.Vertex3( rect.xMax, rect.yMax, 0 ); - GL.Vertex3( rect.xMin, rect.yMax, 0 ); - GL.End(); - } - - public static void DrawBox(Rect box, Color color, float width) - { - Vector2 p1 = new Vector2(box.xMin, box.yMin); - Vector2 p2 = new Vector2(box.xMax, box.yMin); - Vector2 p3 = new Vector2(box.xMax, box.yMax); - Vector2 p4 = new Vector2(box.xMin, box.yMax); - DrawLine(p1, p2, color, width); - DrawLine(p2, p3, color, width); - DrawLine(p3, p4, color, width); - DrawLine(p4, p1, color, width); - } - - public static void DrawBox(Vector2 topLeftCorner, Vector2 bottomRightCorner, Color color, float width) - { - Rect box = new Rect(topLeftCorner.x, topLeftCorner.y, bottomRightCorner.x - topLeftCorner.x, bottomRightCorner.y - topLeftCorner.y); - DrawBox(box, color, width); - } - - public static void DrawRoundedBox(Rect box, float radius, Color color, float width) - { - Vector2 p1, p2, p3, p4, p5, p6, p7, p8; - p1 = new Vector2(box.xMin + radius, box.yMin); - p2 = new Vector2(box.xMax - radius, box.yMin); - p3 = new Vector2(box.xMax, box.yMin + radius); - p4 = new Vector2(box.xMax, box.yMax - radius); - p5 = new Vector2(box.xMax - radius, box.yMax); - p6 = new Vector2(box.xMin + radius, box.yMax); - p7 = new Vector2(box.xMin, box.yMax - radius); - p8 = new Vector2(box.xMin, box.yMin + radius); - - DrawLine(p1, p2, color, width); - DrawLine(p3, p4, color, width); - DrawLine(p5, p6, color, width); - DrawLine(p7, p8, color, width); - - Vector2 t1, t2; - float halfRadius = radius / 2; - - t1 = new Vector2(p8.x, p8.y + halfRadius); - t2 = new Vector2(p1.x - halfRadius, p1.y); - DrawBezier(p8, t1, p1, t2, color, width); - - t1 = new Vector2(p2.x + halfRadius, p2.y); - t2 = new Vector2(p3.x, p3.y - halfRadius); - DrawBezier(p2, t1, p3, t2, color, width); - - t1 = new Vector2(p4.x, p4.y + halfRadius); - t2 = new Vector2(p5.x + halfRadius, p5.y); - DrawBezier(p4, t1, p5, t2, color, width); - - t1 = new Vector2(p6.x - halfRadius, p6.y); - t2 = new Vector2(p7.x, p7.y + halfRadius); - DrawBezier(p6, t1, p7, t2, color, width); - } - - public static void DrawConnectingCurve(Vector2 start, Vector2 end, Color color, float width) - { - Vector2 distance = start - end; - - Vector2 tangentA = start; - tangentA.x -= distance.x * 0.5f; - Vector2 tangentB = end; - tangentB.x += distance.x * 0.5f; - - int segments = Mathf.FloorToInt((distance.magnitude / 20) * 3); - - DrawBezier(start, tangentA, end, tangentB, color, width, segments); - - Vector2 pA = CubeBezier(start, tangentA, end, tangentB, 0.6f); - Vector2 pB = CubeBezier(start, tangentA, end, tangentB, 0.7f); - - float arrowHeadSize = 5; - - Vector2 arrowPosA = pB; - Vector2 arrowPosB = arrowPosA; - Vector2 arrowPosC = arrowPosA; - - Vector2 dir = (pB - pA).normalized; - - arrowPosB.x += dir.y * arrowHeadSize; - arrowPosB.y -= dir.x * arrowHeadSize; - arrowPosB -= dir * arrowHeadSize; - - arrowPosC.x -= dir.y * arrowHeadSize; - arrowPosC.y += dir.x * arrowHeadSize; - arrowPosC -= dir * arrowHeadSize; - - DrawLine(arrowPosA, arrowPosB, color, 1.025f); - DrawLine(arrowPosA, arrowPosC, color, 1.025f); - } - - public static void DrawBezier(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width) - { - int segments = Mathf.FloorToInt((start - end).magnitude / 20) * 3; // Three segments per distance of 20 - DrawBezier(start, startTangent, end, endTangent, color, width, segments); - } - - public static void DrawBezier(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, int segments) - { - Vector2 startVector = CubeBezier(start, startTangent, end, endTangent, 0); - for (int i = 1; i <= segments; i++) - { - Vector2 endVector = CubeBezier(start, startTangent, end, endTangent, i / (float)segments); - DrawLine(startVector, endVector, color, width); - startVector = endVector; - } - } - - private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) - { - float rt = 1 - t; - float rtt = rt * t; - return rt * rt * rt * s + 3 * rt * rtt * st + 3 * rtt * t * et + t * t * t * e; - } - } -} \ No newline at end of file diff --git a/Assets/Fungus/Scripts/Editor/GLDraw.cs.meta b/Assets/Fungus/Scripts/Editor/GLDraw.cs.meta deleted file mode 100644 index 6f3fb05c..00000000 --- a/Assets/Fungus/Scripts/Editor/GLDraw.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5184535fd41514a0ebd42c1d70a53545 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: From 5ddb670ef88531a2304ebf0203263525c30c039f Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 09:38:21 -0800 Subject: [PATCH 2/7] Removed unused GLLineDraw resources --- Assets/Fungus/Resources/GLLineDraw.mat | 138 ------------------ Assets/Fungus/Resources/GLLineDraw.mat.meta | 8 - Assets/Fungus/Resources/GLLineDraw.shader | 11 -- .../Fungus/Resources/GLLineDraw.shader.meta | 9 -- 4 files changed, 166 deletions(-) delete mode 100644 Assets/Fungus/Resources/GLLineDraw.mat delete mode 100644 Assets/Fungus/Resources/GLLineDraw.mat.meta delete mode 100644 Assets/Fungus/Resources/GLLineDraw.shader delete mode 100644 Assets/Fungus/Resources/GLLineDraw.shader.meta diff --git a/Assets/Fungus/Resources/GLLineDraw.mat b/Assets/Fungus/Resources/GLLineDraw.mat deleted file mode 100644 index d6af24a8..00000000 --- a/Assets/Fungus/Resources/GLLineDraw.mat +++ /dev/null @@ -1,138 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: GLLineDraw - m_Shader: {fileID: 4800000, guid: ef64b0d30343049d4a634192975fab73, type: 3} - m_ShaderKeywords: - m_LightmapFlags: 5 - m_CustomRenderQueue: -1 - stringTagMap: {} - m_SavedProperties: - serializedVersion: 2 - m_TexEnvs: - data: - first: - name: _MainTex - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _BumpMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailNormalMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _ParallaxMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _OcclusionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _EmissionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailMask - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailAlbedoMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _MetallicGlossMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - data: - first: - name: _SrcBlend - second: 1 - data: - first: - name: _DstBlend - second: 0 - data: - first: - name: _Cutoff - second: .5 - data: - first: - name: _Parallax - second: .0199999996 - data: - first: - name: _ZWrite - second: 1 - data: - first: - name: _Glossiness - second: .5 - data: - first: - name: _BumpScale - second: 1 - data: - first: - name: _OcclusionStrength - second: 1 - data: - first: - name: _DetailNormalMapScale - second: 1 - data: - first: - name: _UVSec - second: 0 - data: - first: - name: _Mode - second: 0 - data: - first: - name: _Metallic - second: 0 - m_Colors: - data: - first: - name: _EmissionColor - second: {r: 0, g: 0, b: 0, a: 1} - data: - first: - name: _Color - second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/Fungus/Resources/GLLineDraw.mat.meta b/Assets/Fungus/Resources/GLLineDraw.mat.meta deleted file mode 100644 index 9d6a27d2..00000000 --- a/Assets/Fungus/Resources/GLLineDraw.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4209d966cfca44792ad45389a996015e -timeCreated: 1434115586 -licenseType: Free -NativeFormatImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Fungus/Resources/GLLineDraw.shader b/Assets/Fungus/Resources/GLLineDraw.shader deleted file mode 100644 index 761be92f..00000000 --- a/Assets/Fungus/Resources/GLLineDraw.shader +++ /dev/null @@ -1,11 +0,0 @@ -Shader "Lines/Colored Blended" { - SubShader { - Pass { - Blend SrcAlpha OneMinusSrcAlpha - ZWrite Off Cull Off Fog { Mode Off } - BindChannels { - Bind "vertex", vertex Bind "color", color - } - } - } -} diff --git a/Assets/Fungus/Resources/GLLineDraw.shader.meta b/Assets/Fungus/Resources/GLLineDraw.shader.meta deleted file mode 100644 index e94f8e19..00000000 --- a/Assets/Fungus/Resources/GLLineDraw.shader.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: ef64b0d30343049d4a634192975fab73 -timeCreated: 1434114816 -licenseType: Free -ShaderImporter: - defaultTextures: [] - userData: - assetBundleName: - assetBundleVariant: From c61f4b05ce4cf8333ccc94c0d36ca4ec24a2114e Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 11:20:54 -0800 Subject: [PATCH 3/7] EditorResources now uses SerializedObject to maintain asset references --- .../FungusEditorResources.asset | 59 ++++++ .../FungusEditorResources.asset.meta | 8 + .../Scripts/Editor/FungusEditorResources.cs | 171 +++++++++++++----- .../Editor/FungusEditorResourcesGenerated.cs | 64 ++++--- 4 files changed, 222 insertions(+), 80 deletions(-) create mode 100644 Assets/Fungus/EditorResources/FungusEditorResources.asset create mode 100644 Assets/Fungus/EditorResources/FungusEditorResources.asset.meta diff --git a/Assets/Fungus/EditorResources/FungusEditorResources.asset b/Assets/Fungus/EditorResources/FungusEditorResources.asset new file mode 100644 index 00000000..f8d40f35 --- /dev/null +++ b/Assets/Fungus/EditorResources/FungusEditorResources.asset @@ -0,0 +1,59 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d2af387304e4b454b9ce8b815799cad0, type: 3} + m_Name: FungusEditorResources + m_EditorClassIdentifier: + updateOnReloadScripts: 0 + add: + free: {fileID: 2800000, guid: 24a867d6b4cdda04cb3aa3350f9ec7d0, type: 3} + pro: {fileID: 2800000, guid: 4e43c476b4a7a49a08c37378fb01ce99, type: 3} + add_small: + free: {fileID: 2800000, guid: 288aff1a0e5c14fd3a0039d24149df73, type: 3} + pro: {fileID: 2800000, guid: 64534dfaa17844231a9a9dd2df89d0db, type: 3} + delete: + free: {fileID: 2800000, guid: d6fc8a97e8a5b0947a49b780f787e504, type: 3} + pro: {fileID: 2800000, guid: 29c4d29b1678042a5b3516c732ccc507, type: 3} + down: + free: {fileID: 2800000, guid: 51a973f446c2e664582861480cce6215, type: 3} + pro: {fileID: 2800000, guid: 5a87a7d3683164a238377d948572805f, type: 3} + duplicate: + free: {fileID: 2800000, guid: c97f334c466215a4f93eff31de3c1591, type: 3} + pro: {fileID: 2800000, guid: 2f17490d993c84bd7872ef6588ffba47, type: 3} + up: + free: {fileID: 2800000, guid: 8f1242ad894201f43b2b6d52fd990f77, type: 3} + pro: {fileID: 2800000, guid: 2a76a781db2994b33b83cd84b8835da7, type: 3} + choice_node_off: + free: {fileID: 2800000, guid: 7b6fc04aac74540e39e9502da5312ce7, type: 3} + pro: {fileID: 0} + choice_node_on: + free: {fileID: 2800000, guid: cfc05494b71a0446182868aab5f7febf, type: 3} + pro: {fileID: 0} + command_background: + free: {fileID: 2800000, guid: a5c9a4271b3de4e4f86eff7f8a1bd768, type: 3} + pro: {fileID: 0} + event_node_off: + free: {fileID: 2800000, guid: 0e16a209826864df7b05f6d3901aae7a, type: 3} + pro: {fileID: 0} + event_node_on: + free: {fileID: 2800000, guid: 9434488a4efb54da5986eba5d5619baf, type: 3} + pro: {fileID: 0} + play_big: + free: {fileID: 2800000, guid: bff2ba39f5f4448589e80522ebfcd0a0, type: 3} + pro: {fileID: 0} + play_small: + free: {fileID: 2800000, guid: a48a2b9b06deb469d9da1777b094521b, type: 3} + pro: {fileID: 0} + process_node_off: + free: {fileID: 2800000, guid: ea3a4228e6c214149bfe5c741b56ae0c, type: 3} + pro: {fileID: 0} + process_node_on: + free: {fileID: 2800000, guid: c2dceb780784240ccbe8d3cde89f7671, type: 3} + pro: {fileID: 0} diff --git a/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta b/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta new file mode 100644 index 00000000..c92acc45 --- /dev/null +++ b/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 29cae11326cb84802b83fc3ff25a47e8 +timeCreated: 1478978272 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs index a3c9f948..109c3dda 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs @@ -3,6 +3,7 @@ using UnityEngine; using UnityEditor; +using UnityEditor.Callbacks; using System; using System.IO; using System.Linq; @@ -10,58 +11,102 @@ using System.Collections.Generic; namespace Fungus.EditorUtils { - internal static partial class FungusEditorResources + [CustomEditor(typeof(FungusEditorResources))] + internal class FungusEditorResourcesInspector : Editor { - private static Dictionary textures = new Dictionary(); - private static readonly string editorResourcesFolderName = "\"EditorResources\""; - - static FungusEditorResources() + public override void OnInspectorGUI() { - LoadTexturesFromNames(); + if (serializedObject.FindProperty("updateOnReloadScripts").boolValue) + { + GUILayout.Label("Updating..."); + } + else + { + if (GUILayout.Button("Sync with EditorResources folder")) + { + FungusEditorResources.GenerateResourcesScript(); + } + + DrawDefaultInspector(); + } } + } - private static void LoadTexturesFromNames() + internal partial class FungusEditorResources : ScriptableObject + { + [Serializable] + internal class EditorTexture { - var baseDirectories = AssetDatabase.FindAssets(editorResourcesFolderName).Select( - guid => AssetDatabase.GUIDToAssetPath(guid) - ).ToArray(); - - foreach (var name in resourceNames) + [SerializeField] private Texture2D free; + [SerializeField] private Texture2D pro; + + public Texture2D Texture2D { - LoadTexturesFromGUIDs(AssetDatabase.FindAssets(name + " t:Texture2D", baseDirectories)); + get { return EditorGUIUtility.isProSkin && pro != null ? pro : free; } } - } - private static void LoadAllTexturesInFolder() - { - var rootGuid = AssetDatabase.FindAssets(editorResourcesFolderName)[0]; - var root = AssetDatabase.GUIDToAssetPath(rootGuid); - LoadTexturesFromGUIDs(AssetDatabase.FindAssets("t:Texture2D", new [] { root })); + public EditorTexture(Texture2D free, Texture2D pro) + { + this.free = free; + this.pro = pro; + } } - private static void LoadTexturesFromGUIDs(string[] guids) + private static FungusEditorResources instance; + private static readonly string editorResourcesFolderName = "\"EditorResources\""; + [SerializeField] [HideInInspector] private bool updateOnReloadScripts = false; + + internal static FungusEditorResources Instance { - var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).OrderBy(path => path.ToLower().Contains("/pro/")); - - foreach (var path in paths) + get { - if (path.ToLower().Contains("/pro/") && !EditorGUIUtility.isProSkin) + if (instance == null) { - return; + var guids = AssetDatabase.FindAssets("FungusEditorResources t:FungusEditorResources"); + + if (guids.Length == 0) + { + instance = ScriptableObject.CreateInstance(typeof(FungusEditorResources)) as FungusEditorResources; + AssetDatabase.CreateAsset(instance, GetRootFolder() + "/FungusEditorResources.asset"); + UpdateTextureReferences(instance); + AssetDatabase.SaveAssets(); + } + else + { + if (guids.Length > 1) + { + Debug.LogWarning("Multiple FungusEditorResources assets found!"); + } + + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + instance = AssetDatabase.LoadAssetAtPath(path, typeof(FungusEditorResources)) as FungusEditorResources; + } } - var texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D; - textures[texture.name] = texture; + + return instance; } } - [MenuItem("Tools/Fungus/Utilities/Update Editor Resources Script")] - private static void GenerateResourcesScript() + private static string GetRootFolder() { - textures.Clear(); - LoadAllTexturesInFolder(); + var rootGuid = AssetDatabase.FindAssets(editorResourcesFolderName)[0]; + return AssetDatabase.GUIDToAssetPath(rootGuid); + } - var guid = AssetDatabase.FindAssets("FungusEditorResources t:MonoScript")[0]; - var relativePath = AssetDatabase.GUIDToAssetPath(guid).Replace("FungusEditorResources.cs", "FungusEditorResourcesGenerated.cs"); + internal static void GenerateResourcesScript() + { + // Get all unique filenames + var textureNames = new HashSet(); + var guids = AssetDatabase.FindAssets("t:Texture2D", new [] { GetRootFolder() }); + var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)); + + foreach (var path in paths) + { + textureNames.Add(Path.GetFileNameWithoutExtension(path)); + } + + var scriptGuid = AssetDatabase.FindAssets("FungusEditorResources t:MonoScript")[0]; + var relativePath = AssetDatabase.GUIDToAssetPath(scriptGuid).Replace("FungusEditorResources.cs", "FungusEditorResourcesGenerated.cs"); var absolutePath = Application.dataPath + relativePath.Substring("Assets".Length); using (var writer = new StreamWriter(absolutePath)) @@ -73,43 +118,75 @@ namespace Fungus.EditorUtils writer.WriteLine(""); writer.WriteLine("namespace Fungus.EditorUtils"); writer.WriteLine("{"); - writer.WriteLine(" internal static partial class FungusEditorResources"); + writer.WriteLine(" internal partial class FungusEditorResources : ScriptableObject"); writer.WriteLine(" {"); - writer.WriteLine(" private static readonly string[] resourceNames = new [] {"); - foreach (var pair in textures) + foreach (var name in textureNames) { - writer.WriteLine(" \"" + pair.Key + "\","); + writer.WriteLine(" [SerializeField] private EditorTexture " + name + ";"); } - writer.WriteLine(" };"); writer.WriteLine(""); - foreach (var pair in textures) + foreach (var name in textureNames) { - var name = pair.Key; var pascalCase = string.Join("", name.Split(new [] { '_' }, StringSplitOptions.RemoveEmptyEntries).Select( s => s.Substring(0, 1).ToUpper() + s.Substring(1)).ToArray() ); - writer.WriteLine(" public static Texture2D " + pascalCase + " { get { return GetTexture(\"" + name + "\"); } }"); + writer.WriteLine(" public static Texture2D " + pascalCase + " { get { return Instance." + name + ".Texture2D; } }"); } writer.WriteLine(" }"); writer.WriteLine("}"); } + Instance.updateOnReloadScripts = true; AssetDatabase.ImportAsset(relativePath); } - private static Texture2D GetTexture(string name) + [DidReloadScripts] + private static void OnDidReloadScripts() { - Texture2D texture; - if (!textures.TryGetValue(name, out texture)) + if (Instance.updateOnReloadScripts) + { + UpdateTextureReferences(Instance); + } + } + + private static void UpdateTextureReferences(FungusEditorResources instance) + { + // Iterate through all fields in class and set texture references + var serializedObject = new SerializedObject(instance); + var prop = serializedObject.GetIterator(); + var rootFolder = new [] { GetRootFolder() }; + + prop.NextVisible(true); + while (prop.NextVisible(false)) { - Debug.LogWarning("Texture \"" + name + "\" not found!"); + if (prop.propertyType == SerializedPropertyType.Generic) + { + var guids = AssetDatabase.FindAssets(prop.name + " t:Texture2D", rootFolder); + var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).Where( + path => path.Contains(prop.name + ".") + ); + + foreach (var path in paths) + { + var texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D; + if (path.ToLower().Contains("/pro/")) + { + prop.FindPropertyRelative("pro").objectReferenceValue = texture; + } + else + { + prop.FindPropertyRelative("free").objectReferenceValue = texture; + } + } + } } - - return texture; + + instance.updateOnReloadScripts = false; + serializedObject.ApplyModifiedPropertiesWithoutUndo(); } } } diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs index e2eab920..27b06e77 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs @@ -5,40 +5,38 @@ using UnityEngine; namespace Fungus.EditorUtils { - internal static partial class FungusEditorResources + internal partial class FungusEditorResources : ScriptableObject { - private static readonly string[] resourceNames = new [] { - "add", - "add_small", - "delete", - "down", - "duplicate", - "up", - "choice_node_off", - "choice_node_on", - "command_background", - "event_node_off", - "event_node_on", - "play_big", - "play_small", - "process_node_off", - "process_node_on", - }; + [SerializeField] private EditorTexture add; + [SerializeField] private EditorTexture add_small; + [SerializeField] private EditorTexture delete; + [SerializeField] private EditorTexture down; + [SerializeField] private EditorTexture duplicate; + [SerializeField] private EditorTexture up; + [SerializeField] private EditorTexture choice_node_off; + [SerializeField] private EditorTexture choice_node_on; + [SerializeField] private EditorTexture command_background; + [SerializeField] private EditorTexture event_node_off; + [SerializeField] private EditorTexture event_node_on; + [SerializeField] private EditorTexture play_big; + [SerializeField] private EditorTexture play_small; + [SerializeField] private EditorTexture process_node_off; + [SerializeField] private EditorTexture process_node_on; - public static Texture2D Add { get { return GetTexture("add"); } } - public static Texture2D AddSmall { get { return GetTexture("add_small"); } } - public static Texture2D Delete { get { return GetTexture("delete"); } } - public static Texture2D Down { get { return GetTexture("down"); } } - public static Texture2D Duplicate { get { return GetTexture("duplicate"); } } - public static Texture2D Up { get { return GetTexture("up"); } } - public static Texture2D ChoiceNodeOff { get { return GetTexture("choice_node_off"); } } - public static Texture2D ChoiceNodeOn { get { return GetTexture("choice_node_on"); } } - public static Texture2D CommandBackground { get { return GetTexture("command_background"); } } - public static Texture2D EventNodeOff { get { return GetTexture("event_node_off"); } } - public static Texture2D EventNodeOn { get { return GetTexture("event_node_on"); } } - public static Texture2D PlayBig { get { return GetTexture("play_big"); } } - public static Texture2D PlaySmall { get { return GetTexture("play_small"); } } - public static Texture2D ProcessNodeOff { get { return GetTexture("process_node_off"); } } - public static Texture2D ProcessNodeOn { get { return GetTexture("process_node_on"); } } + public static Texture2D Add { get { return Instance.add.Texture2D; } } + public static Texture2D AddSmall { get { return Instance.add_small.Texture2D; } } + public static Texture2D Delete { get { return Instance.delete.Texture2D; } } + public static Texture2D Down { get { return Instance.down.Texture2D; } } + public static Texture2D Duplicate { get { return Instance.duplicate.Texture2D; } } + public static Texture2D Up { get { return Instance.up.Texture2D; } } + public static Texture2D ChoiceNodeOff { get { return Instance.choice_node_off.Texture2D; } } + public static Texture2D ChoiceNodeOn { get { return Instance.choice_node_on.Texture2D; } } + public static Texture2D CommandBackground { get { return Instance.command_background.Texture2D; } } + public static Texture2D EventNodeOff { get { return Instance.event_node_off.Texture2D; } } + public static Texture2D EventNodeOn { get { return Instance.event_node_on.Texture2D; } } + public static Texture2D PlayBig { get { return Instance.play_big.Texture2D; } } + public static Texture2D PlaySmall { get { return Instance.play_small.Texture2D; } } + public static Texture2D ProcessNodeOff { get { return Instance.process_node_off.Texture2D; } } + public static Texture2D ProcessNodeOn { get { return Instance.process_node_on.Texture2D; } } } } From 8be8b378c26451375e0f903f4c8d6075eaabde62 Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 14:08:58 -0800 Subject: [PATCH 4/7] Fixed compatibility with Unity 5.0 and 5.1 and handled reimporting resources asset --- .../Scripts/Editor/FungusEditorResources.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs index 109c3dda..ca9c2c21 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs @@ -8,6 +8,9 @@ using System; using System.IO; using System.Linq; using System.Collections.Generic; +#if UNITY_5_0 || UNITY_5_1 +using System.Reflection; +#endif namespace Fungus.EditorUtils { @@ -32,6 +35,26 @@ namespace Fungus.EditorUtils } } + internal class EditorResourcesPostProcessor : AssetPostprocessor + { + private static void OnPostprocessAllAssets(string[] importedAssets, string[] _, string[] __, string[] ___) + { + foreach (var path in importedAssets) + { + if (path.EndsWith("FungusEditorResources.asset")) + { + var asset = AssetDatabase.LoadAssetAtPath(path, typeof(FungusEditorResources)) as FungusEditorResources; + if (asset != null) + { + FungusEditorResources.UpdateTextureReferences(asset); + AssetDatabase.SaveAssets(); + return; + } + } + } + } + } + internal partial class FungusEditorResources : ScriptableObject { [Serializable] @@ -68,8 +91,6 @@ namespace Fungus.EditorUtils { instance = ScriptableObject.CreateInstance(typeof(FungusEditorResources)) as FungusEditorResources; AssetDatabase.CreateAsset(instance, GetRootFolder() + "/FungusEditorResources.asset"); - UpdateTextureReferences(instance); - AssetDatabase.SaveAssets(); } else { @@ -153,9 +174,9 @@ namespace Fungus.EditorUtils } } - private static void UpdateTextureReferences(FungusEditorResources instance) + internal static void UpdateTextureReferences(FungusEditorResources instance) { - // Iterate through all fields in class and set texture references + // Iterate through all fields in instance and set texture references var serializedObject = new SerializedObject(instance); var prop = serializedObject.GetIterator(); var rootFolder = new [] { GetRootFolder() }; @@ -186,7 +207,15 @@ namespace Fungus.EditorUtils } instance.updateOnReloadScripts = false; + + // The ApplyModifiedPropertiesWithoutUndo() function wasn't documented until Unity 5.2 +#if UNITY_5_0 || UNITY_5_1 + var flags = BindingFlags.Instance | BindingFlags.NonPublic; + var applyMethod = typeof(SerializedObject).GetMethod("ApplyModifiedPropertiesWithoutUndo", flags); + applyMethod.Invoke(serializedObject, null); +#else serializedObject.ApplyModifiedPropertiesWithoutUndo(); +#endif } } } From dd5bdf6dcf7c396ec23ac441a1c7044472677bad Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 17:12:54 -0800 Subject: [PATCH 5/7] Reimplemented cut/copy/paste using SerializedObjects -Added cut/copy/paste functionality -Replaced DuplicateBlocks() functions with calls to Copy() and Paste() to reduce duplicated code --- .../Fungus/Scripts/Editor/FlowchartWindow.cs | 245 +++++++++++++----- 1 file changed, 177 insertions(+), 68 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs index 9c49352f..9a631d1f 100644 --- a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs +++ b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs @@ -8,11 +8,94 @@ using System; using System.Linq; using System.Collections.Generic; using System.Reflection; +using Object = UnityEngine.Object; namespace Fungus.EditorUtils { public class FlowchartWindow : EditorWindow { + protected class ClipboardObject + { + internal SerializedObject serializedObject; + internal Type type; + + internal ClipboardObject(Object obj) + { + serializedObject = new SerializedObject(obj); + type = obj.GetType(); + } + } + + protected class BlockCopy + { + private SerializedObject block = null; + private List commands = new List(); + private ClipboardObject eventHandler = null; + + internal BlockCopy(Block block) + { + this.block = new SerializedObject(block); + foreach (var command in block.CommandList) + { + commands.Add(new ClipboardObject(command)); + } + if (block._EventHandler != null) + { + eventHandler = new ClipboardObject(block._EventHandler); + } + } + + private void CopyProperties(SerializedObject source, Object dest, params SerializedPropertyType[] excludeTypes) + { + var newSerializedObject = new SerializedObject(dest); + var prop = source.GetIterator(); + while (prop.NextVisible(true)) + { + if (!excludeTypes.Contains(prop.propertyType)) + { + newSerializedObject.CopyFromSerializedProperty(prop); + } + } + + newSerializedObject.ApplyModifiedProperties(); + } + + internal Block PasteBlock(Flowchart flowchart) + { + var newBlock = FlowchartWindow.CreateBlock(flowchart, Vector2.zero); + + // Copy all command serialized properties + // Copy references to match duplication behavior + foreach (var command in commands) + { + var newCommand = Undo.AddComponent(flowchart.gameObject, command.type) as Command; + CopyProperties(command.serializedObject, newCommand); + newBlock.CommandList.Add(newCommand); + } + + // Copy event handler + if (eventHandler != null) + { + var newEventHandler = Undo.AddComponent(flowchart.gameObject, eventHandler.type) as EventHandler; + CopyProperties(eventHandler.serializedObject, newEventHandler); + newBlock._EventHandler = newEventHandler; + } + + // Copy block properties, but do not copy references because those were just assigned + CopyProperties( + block, + newBlock, + SerializedPropertyType.ObjectReference, + SerializedPropertyType.Generic, + SerializedPropertyType.ArraySize + ); + + newBlock.BlockName = flowchart.GetUniqueBlockKey(block.FindProperty("blockName").stringValue + " (Copy)"); + + return newBlock; + } + } + public static List deleteList = new List(); protected List windowBlockMap = new List(); @@ -39,6 +122,8 @@ namespace Fungus.EditorUtils protected Vector2 startSelectionBoxPosition = -Vector2.one; protected List mouseDownSelectionState = new List(); + protected List copyList = new List(); + // Context Click occurs on MouseDown which interferes with panning // Track right click positions manually to show menus on MouseUp protected Vector2 rightClickDown = -Vector2.one; @@ -66,6 +151,7 @@ namespace Fungus.EditorUtils nodeStyle.wordWrap = true; addTexture = Resources.Load("Icons/add_small") as Texture2D; + copyList.Clear(); } protected virtual void OnInspectorUpdate() @@ -155,6 +241,11 @@ namespace Fungus.EditorUtils { Undo.DestroyObjectImmediate(command); } + + if (deleteBlock._EventHandler != null) + { + Undo.DestroyObjectImmediate(deleteBlock._EventHandler); + } Undo.DestroyObjectImmediate((Block)deleteBlock); flowchart.ClearSelectedCommands(); @@ -512,14 +603,26 @@ namespace Fungus.EditorUtils // Use a copy because flowchart.SelectedBlocks gets modified var blockList = new List(flowchart.SelectedBlocks); - menu.AddItem(new GUIContent ("Duplicate"), false, DuplicateBlocks, blockList); + menu.AddItem(new GUIContent ("Copy"), false, () => Copy(flowchart)); + menu.AddItem(new GUIContent ("Cut"), false, () => Cut(flowchart)); + menu.AddItem(new GUIContent ("Duplicate"), false, () => Duplicate(flowchart)); menu.AddItem(new GUIContent ("Delete"), false, DeleteBlocks, blockList); } // Clicked on empty space in grid else { DeselectAll(flowchart); + menu.AddItem(new GUIContent("Add Block"), false, () => CreateBlock(flowchart, mousePosition / flowchart.Zoom - flowchart.ScrollPos)); + + if (copyList.Count > 0) + { + menu.AddItem(new GUIContent("Paste"), false, () => Paste(flowchart, mousePosition)); + } + else + { + menu.AddDisabledItem(new GUIContent("Paste")); + } } var menuRect = new Rect(); @@ -1042,71 +1145,6 @@ namespace Fungus.EditorUtils blocks.ForEach(block => FlowchartWindow.deleteList.Add(block)); } - protected static void DuplicateBlocks(object obj) - { - DuplicateBlocks(obj, new Vector2(20, 0)); - } - - protected static void DuplicateBlocks(object obj, Vector2 offset) - { - var flowchart = GetFlowchart(); - - Undo.RecordObject(flowchart, "Select"); - flowchart.ClearSelectedBlocks(); - - var blocks = obj as List; - - foreach (var block in blocks) - { - Vector2 newPosition = block._NodeRect.position + offset; - - Block oldBlock = block; - - Block newBlock = FlowchartWindow.CreateBlock(flowchart, newPosition); - newBlock.BlockName = flowchart.GetUniqueBlockKey(oldBlock.BlockName + " (Copy)"); - - Undo.RecordObject(newBlock, "Duplicate Block"); - - var commandList = oldBlock.CommandList; - foreach (var command in commandList) - { - if (ComponentUtility.CopyComponent(command)) - { - if (ComponentUtility.PasteComponentAsNew(flowchart.gameObject)) - { - Command[] commands = flowchart.GetComponents(); - Command pastedCommand = commands.Last(); - if (pastedCommand != null) - { - pastedCommand.ItemId = flowchart.NextItemId(); - newBlock.CommandList.Add(pastedCommand); - } - } - - // This stops the user pasting the command manually into another game object. - ComponentUtility.CopyComponent(flowchart.transform); - } - } - - if (oldBlock._EventHandler != null) - { - if (ComponentUtility.CopyComponent(oldBlock._EventHandler)) - { - if (ComponentUtility.PasteComponentAsNew(flowchart.gameObject)) - { - EventHandler[] eventHandlers = flowchart.GetComponents(); - EventHandler pastedEventHandler = eventHandlers.Last(); - if (pastedEventHandler != null) - { - pastedEventHandler.ParentBlock = newBlock; - newBlock._EventHandler = pastedEventHandler; - } - } - } - } - } - } - protected static void ShowBlockInspector(Flowchart flowchart) { if (blockInspector == null) @@ -1149,18 +1187,74 @@ namespace Fungus.EditorUtils return Event.current.shift || EditorGUI.actionKey; } + protected virtual void Copy(Flowchart flowchart) + { + copyList.Clear(); + + foreach (var block in flowchart.SelectedBlocks) + { + copyList.Add(new BlockCopy(block)); + } + } + + protected virtual void Cut(Flowchart flowchart) + { + Copy(flowchart); + Undo.RecordObject(flowchart, "Cut"); + DeleteBlocks(flowchart.SelectedBlocks); + } + + // Center is position in unscaled window space + protected virtual void Paste(Flowchart flowchart, Vector2 center, bool relative = false) + { + Undo.RecordObject(flowchart, "Deselect"); + DeselectAll(flowchart); + + var pasteList = new List(); + + foreach (var copy in copyList) + { + pasteList.Add(copy.PasteBlock(flowchart)); + } + + var copiedCenter = GetBlockCenter(flowchart, pasteList.ToArray()) + flowchart.ScrollPos; + var delta = relative ? center : (center / flowchart.Zoom - copiedCenter); + + foreach (var block in pasteList) + { + var tempRect = block._NodeRect; + tempRect.position += delta; + block._NodeRect = tempRect; + } + } + + protected virtual void Duplicate(Flowchart flowchart) + { + var tempCopyList = new List(copyList); + Copy(flowchart); + Paste(flowchart, new Vector2(20, 0), true); + copyList = tempCopyList; + } + protected virtual void ValidateCommands(Flowchart flowchart) { if (Event.current.type == EventType.ValidateCommand) { var c = Event.current.commandName; - if (c == "Delete" || c == "Duplicate") + if (c == "Copy" || c == "Cut" || c == "Delete" || c == "Duplicate") { if (flowchart.SelectedBlocks.Count > 0) { Event.current.Use(); } } + else if (c == "Paste") + { + if (copyList.Count > 0) + { + Event.current.Use(); + } + } else if (c == "SelectAll") { Event.current.Use(); @@ -1174,13 +1268,28 @@ namespace Fungus.EditorUtils { switch (Event.current.commandName) { + case "Copy": + Copy(flowchart); + Event.current.Use(); + break; + + case "Cut": + Cut(flowchart); + Event.current.Use(); + break; + + case "Paste": + Paste(flowchart, position.center - position.position); + Event.current.Use(); + break; + case "Delete": DeleteBlocks(flowchart.SelectedBlocks); Event.current.Use(); break; case "Duplicate": - DuplicateBlocks(new List(flowchart.SelectedBlocks)); + Duplicate(flowchart); Event.current.Use(); break; From bb0aa56ad08b5c30e38500c2ac840c68c492fade Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 17:46:56 -0800 Subject: [PATCH 6/7] Updated paste function to assign command ItemIds and event handler parent blocks --- Assets/Fungus/Scripts/Editor/FlowchartWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs index b89e197b..761ddc9d 100644 --- a/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs +++ b/Assets/Fungus/Scripts/Editor/FlowchartWindow.cs @@ -3,7 +3,6 @@ using UnityEngine; using UnityEditor; -using UnityEditorInternal; using System; using System.Linq; using System.Collections.Generic; @@ -70,6 +69,7 @@ namespace Fungus.EditorUtils { var newCommand = Undo.AddComponent(flowchart.gameObject, command.type) as Command; CopyProperties(command.serializedObject, newCommand); + newCommand.ItemId = flowchart.NextItemId(); newBlock.CommandList.Add(newCommand); } @@ -78,6 +78,7 @@ namespace Fungus.EditorUtils { var newEventHandler = Undo.AddComponent(flowchart.gameObject, eventHandler.type) as EventHandler; CopyProperties(eventHandler.serializedObject, newEventHandler); + newEventHandler.ParentBlock = newBlock; newBlock._EventHandler = newEventHandler; } From 88ffa62c3f51d095e23352d09583d0b35e71e257 Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Wed, 16 Nov 2016 22:40:57 -0800 Subject: [PATCH 7/7] Added connection_point to FungusEditorResources asset --- Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta | 10 +++++++++- .../Fungus/EditorResources/FungusEditorResources.asset | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta b/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta index f6ebfb64..5244b496 100644 --- a/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta +++ b/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta @@ -7,8 +7,16 @@ PluginImporter: isPreloaded: 0 platformData: Any: - enabled: 1 + enabled: 0 settings: {} + Editor: + enabled: 1 + settings: + DefaultValueInitialized: true + WindowsStoreApps: + enabled: 0 + settings: + CPU: AnyCPU userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Fungus/EditorResources/FungusEditorResources.asset b/Assets/Fungus/EditorResources/FungusEditorResources.asset index f8d40f35..594b27ed 100644 --- a/Assets/Fungus/EditorResources/FungusEditorResources.asset +++ b/Assets/Fungus/EditorResources/FungusEditorResources.asset @@ -39,6 +39,9 @@ MonoBehaviour: command_background: free: {fileID: 2800000, guid: a5c9a4271b3de4e4f86eff7f8a1bd768, type: 3} pro: {fileID: 0} + connection_point: + free: {fileID: 2800000, guid: f08a4c27d7efe4aa6a35348a4e8aec8f, type: 3} + pro: {fileID: 0} event_node_off: free: {fileID: 2800000, guid: 0e16a209826864df7b05f6d3901aae7a, type: 3} pro: {fileID: 0}