Browse Source

Merge pull request #355 from FungusGames/fungus-namespace-353

Fixed CustomGUI class not in Fungus namespace #353
master
Chris Gregan 9 years ago
parent
commit
b9a0c27b7d
  1. 67
      Assets/Fungus/Flowchart/Editor/CustomGUI.cs
  2. 129
      Assets/Fungus/Flowchart/Editor/EditorExtensions.cs
  3. 129
      Assets/Fungus/Flowchart/Editor/EditorZoomArea.cs
  4. 557
      Assets/Fungus/Flowchart/Editor/GLDraw.cs

67
Assets/Fungus/Flowchart/Editor/CustomGUI.cs

@ -4,37 +4,42 @@ using UnityEditor;
using System; using System;
using System.Reflection; using System.Reflection;
/** namespace Fungus
* Utility functions for drawing custom UI in the editor {
*/
public static class CustomGUI
{
public static Texture2D CreateBlackTexture()
{
Texture2D blackTex = new Texture2D(1,2);
blackTex.SetPixel(0, 0, Color.gray);
blackTex.SetPixel(1, 0, Color.black);
blackTex.Apply();
blackTex.hideFlags = HideFlags.DontSave;
return blackTex;
}
public static Texture2D CreateColorTexture(Color color) /**
{ * Utility functions for drawing custom UI in the editor
Texture2D colorTex = new Texture2D(1,1); */
colorTex.SetPixel(0, 0, color); public static class CustomGUI
colorTex.Apply(); {
colorTex.hideFlags = HideFlags.DontSave; public static Texture2D CreateBlackTexture()
return colorTex; {
} Texture2D blackTex = new Texture2D(1,2);
blackTex.SetPixel(0, 0, Color.gray);
public static void DrawLineSeparator(Texture2D blackTex, float width) blackTex.SetPixel(1, 0, Color.black);
{ blackTex.Apply();
GUIStyle separatorStyle = new GUIStyle(GUI.skin.box); blackTex.hideFlags = HideFlags.DontSave;
separatorStyle.fixedWidth = width; return blackTex;
separatorStyle.fixedHeight = 2; }
separatorStyle.margin.top = 10;
separatorStyle.margin.bottom = 10; public static Texture2D CreateColorTexture(Color color)
GUILayout.Box(blackTex,separatorStyle); {
Texture2D colorTex = new Texture2D(1,1);
colorTex.SetPixel(0, 0, color);
colorTex.Apply();
colorTex.hideFlags = HideFlags.DontSave;
return colorTex;
}
public static void DrawLineSeparator(Texture2D blackTex, float width)
{
GUIStyle separatorStyle = new GUIStyle(GUI.skin.box);
separatorStyle.fixedWidth = width;
separatorStyle.fixedHeight = 2;
separatorStyle.margin.top = 10;
separatorStyle.margin.bottom = 10;
GUILayout.Box(blackTex,separatorStyle);
}
} }
} }

129
Assets/Fungus/Flowchart/Editor/EditorExtensions.cs

@ -1,62 +1,67 @@
using UnityEngine; using UnityEngine;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
public static class EditorExtensions namespace Fungus
{ {
/// <summary>
/// FindDerivedTypesFromAssembly allows a user to query all of types derived from a public static class EditorExtensions
/// particular Type at runtime. {
/// Example usage: /// <summary>
/// foreach (System.Type st in EditorUtility.FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(typeof(BaseTimelineEvent)), typeof(BaseTimelineEvent), true)) /// FindDerivedTypesFromAssembly allows a user to query all of types derived from a
/// </summary> /// particular Type at runtime.
/// <param name="assembly">The assembly to search in</param> /// Example usage:
/// <param name="baseType">The base Type from which all returned Types derive</param> /// foreach (System.Type st in EditorUtility.FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(typeof(BaseTimelineEvent)), typeof(BaseTimelineEvent), true))
/// <param name="classOnly">If true, only class Types will be returned</param> /// </summary>
/// <returns></returns> /// <param name="assembly">The assembly to search in</param>
public static System.Type[] FindDerivedTypesFromAssembly(this System.Reflection.Assembly assembly, System.Type baseType, bool classOnly = true) /// <param name="baseType">The base Type from which all returned Types derive</param>
{ /// <param name="classOnly">If true, only class Types will be returned</param>
if (assembly == null) /// <returns></returns>
Debug.LogError("Assembly must be defined"); public static System.Type[] FindDerivedTypesFromAssembly(this System.Reflection.Assembly assembly, System.Type baseType, bool classOnly = true)
if (baseType == null) {
Debug.LogError("Base type must be defined"); if (assembly == null)
Debug.LogError("Assembly must be defined");
// Iterate through all available types in the assembly if (baseType == null)
var types = assembly.GetTypes().Where(type => Debug.LogError("Base type must be defined");
{
if (classOnly && !type.IsClass) // Iterate through all available types in the assembly
return false; var types = assembly.GetTypes().Where(type =>
{
if (baseType.IsInterface) if (classOnly && !type.IsClass)
{ return false;
var it = type.GetInterface(baseType.FullName);
if (baseType.IsInterface)
if (it != null) {
return true; var it = type.GetInterface(baseType.FullName);
}
else if (type.IsSubclassOf(baseType)) if (it != null)
{ return true;
return true; }
} else if (type.IsSubclassOf(baseType))
{
return false; return true;
} }
);
return false;
return types.ToArray(); }
} );
/// <summary> return types.ToArray();
/// A convenient method for calling the above. }
/// Example usage:
/// List<System.Type> subTypes = EditorUtility.FindDerivedTypes(typeof(BaseTimelineEvent)).ToList(); /// <summary>
/// </summary> /// A convenient method for calling the above.
/// <param name="baseType"></param> /// Example usage:
/// <param name="classOnly"></param> /// List<System.Type> subTypes = EditorUtility.FindDerivedTypes(typeof(BaseTimelineEvent)).ToList();
/// <returns></returns> /// </summary>
public static System.Type[] FindDerivedTypes(System.Type baseType, bool classOnly = true) /// <param name="baseType"></param>
{ /// <param name="classOnly"></param>
return FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(baseType), baseType, classOnly); /// <returns></returns>
} public static System.Type[] FindDerivedTypes(System.Type baseType, bool classOnly = true)
} {
return FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(baseType), baseType, classOnly);
}
}
}

129
Assets/Fungus/Flowchart/Editor/EditorZoomArea.cs

@ -2,78 +2,83 @@
using UnityEngine; using UnityEngine;
// Helper Rect extension methods namespace Fungus
public static class RectExtensions
{ {
public static Vector2 TopLeft(this Rect rect)
{
return new Vector2(rect.xMin, rect.yMin);
}
public static Rect ScaleSizeBy(this Rect rect, float scale) // Helper Rect extension methods
public static class RectExtensions
{ {
return rect.ScaleSizeBy(scale, rect.center); public static Vector2 TopLeft(this Rect rect)
} {
return new Vector2(rect.xMin, rect.yMin);
}
public static Rect ScaleSizeBy(this Rect rect, float scale, Vector2 pivotPoint) public static Rect ScaleSizeBy(this Rect rect, float scale)
{ {
Rect result = rect; return rect.ScaleSizeBy(scale, rect.center);
result.x -= pivotPoint.x; }
result.y -= pivotPoint.y;
result.xMin *= scale;
result.xMax *= scale;
result.yMin *= scale;
result.yMax *= scale;
result.x += pivotPoint.x;
result.y += pivotPoint.y;
return result;
}
public static Rect ScaleSizeBy(this Rect rect, Vector2 scale) public static Rect ScaleSizeBy(this Rect rect, float scale, Vector2 pivotPoint)
{ {
return rect.ScaleSizeBy(scale, rect.center); Rect result = rect;
} result.x -= pivotPoint.x;
result.y -= pivotPoint.y;
result.xMin *= scale;
result.xMax *= scale;
result.yMin *= scale;
result.yMax *= scale;
result.x += pivotPoint.x;
result.y += pivotPoint.y;
return result;
}
public static Rect ScaleSizeBy(this Rect rect, Vector2 scale, Vector2 pivotPoint) public static Rect ScaleSizeBy(this Rect rect, Vector2 scale)
{ {
Rect result = rect; return rect.ScaleSizeBy(scale, rect.center);
result.x -= pivotPoint.x; }
result.y -= pivotPoint.y;
result.xMin *= scale.x; public static Rect ScaleSizeBy(this Rect rect, Vector2 scale, Vector2 pivotPoint)
result.xMax *= scale.x; {
result.yMin *= scale.y; Rect result = rect;
result.yMax *= scale.y; result.x -= pivotPoint.x;
result.x += pivotPoint.x; result.y -= pivotPoint.y;
result.y += pivotPoint.y; result.xMin *= scale.x;
return result; result.xMax *= scale.x;
result.yMin *= scale.y;
result.yMax *= scale.y;
result.x += pivotPoint.x;
result.y += pivotPoint.y;
return result;
}
} }
}
public class EditorZoomArea public class EditorZoomArea
{
private const float kEditorWindowTabHeight = 21.0f;
private static Matrix4x4 _prevGuiMatrix;
public static Rect Begin(float zoomScale, Rect screenCoordsArea)
{ {
GUI.EndGroup(); // End the group Unity begins automatically for an EditorWindow to clip out the window tab. This allows us to draw outside of the size of the EditorWindow. private const float kEditorWindowTabHeight = 21.0f;
private static Matrix4x4 _prevGuiMatrix;
Rect clippedArea = screenCoordsArea.ScaleSizeBy(1.0f / zoomScale, screenCoordsArea.TopLeft());
clippedArea.y += kEditorWindowTabHeight;
GUI.BeginGroup(clippedArea);
_prevGuiMatrix = GUI.matrix; public static Rect Begin(float zoomScale, Rect screenCoordsArea)
Matrix4x4 translation = Matrix4x4.TRS(clippedArea.TopLeft(), Quaternion.identity, Vector3.one); {
Matrix4x4 scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f)); GUI.EndGroup(); // End the group Unity begins automatically for an EditorWindow to clip out the window tab. This allows us to draw outside of the size of the EditorWindow.
GUI.matrix = translation * scale * translation.inverse * GUI.matrix;
Rect clippedArea = screenCoordsArea.ScaleSizeBy(1.0f / zoomScale, screenCoordsArea.TopLeft());
clippedArea.y += kEditorWindowTabHeight;
GUI.BeginGroup(clippedArea);
_prevGuiMatrix = GUI.matrix;
Matrix4x4 translation = Matrix4x4.TRS(clippedArea.TopLeft(), Quaternion.identity, Vector3.one);
Matrix4x4 scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f));
GUI.matrix = translation * scale * translation.inverse * GUI.matrix;
return clippedArea;
}
return clippedArea; public static void End()
} {
GUI.matrix = _prevGuiMatrix;
public static void End() GUI.EndGroup();
{ GUI.BeginGroup(new Rect(0.0f, kEditorWindowTabHeight, Screen.width, Screen.height));
GUI.matrix = _prevGuiMatrix; }
GUI.EndGroup();
GUI.BeginGroup(new Rect(0.0f, kEditorWindowTabHeight, Screen.width, Screen.height));
} }
} }

557
Assets/Fungus/Flowchart/Editor/GLDraw.cs

@ -2,287 +2,292 @@ using UnityEngine;
using System.Collections; using System.Collections;
using System; using System;
public class GLDraw namespace Fungus
{ {
/*
* 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
*/
protected static bool clippingEnabled;
protected static Rect clippingBounds;
public static Material lineMaterial = null;
/* @ Credit: "http://cs-people.bu.edu/jalon/cs480/Oct11Lab/clip.c" */
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() public class GLDraw
{
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; * Clipping code: http://forum.unity3d.com/threads/17066-How-to-draw-a-GUI-2D-quot-line-quot?p=230386#post230386
if (Event.current.type != EventType.repaint) * Thick line drawing code: http://unifycommunity.com/wiki/index.php?title=VectorLine
return; */
protected static bool clippingEnabled;
CreateMaterial(); protected static Rect clippingBounds;
// set the current material public static Material lineMaterial = null;
lineMaterial.SetPass( 0 );
GL.Begin( GL.QUADS ); /* @ Credit: "http://cs-people.bu.edu/jalon/cs480/Oct11Lab/clip.c" */
GL.Color( color ); protected static bool clip_test(float p, float q, ref float u1, ref float u2)
GL.Vertex3( rect.xMin, rect.yMin, 0 ); {
GL.Vertex3( rect.xMax, rect.yMin, 0 ); float r;
GL.Vertex3( rect.xMax, rect.yMax, 0 ); bool retval = true;
GL.Vertex3( rect.xMin, rect.yMax, 0 );
GL.End(); if (p < 0.0)
} {
r = q / p;
public static void DrawBox(Rect box, Color color, float width) if (r > u2)
{ retval = false;
Vector2 p1 = new Vector2(box.xMin, box.yMin); else if (r > u1)
Vector2 p2 = new Vector2(box.xMax, box.yMin); u1 = r;
Vector2 p3 = new Vector2(box.xMax, box.yMax); }
Vector2 p4 = new Vector2(box.xMin, box.yMax); else if (p > 0.0)
DrawLine(p1, p2, color, width); {
DrawLine(p2, p3, color, width); r = q / p;
DrawLine(p3, p4, color, width); if (r < u1)
DrawLine(p4, p1, color, width); retval = false;
} else if (r < u2)
u2 = r;
public static void DrawBox(Vector2 topLeftCorner, Vector2 bottomRightCorner, Color color, float width) }
{ else if (q < 0.0)
Rect box = new Rect(topLeftCorner.x, topLeftCorner.y, bottomRightCorner.x - topLeftCorner.x, bottomRightCorner.y - topLeftCorner.y); retval = false;
DrawBox(box, color, width);
} return retval;
}
public static void DrawRoundedBox(Rect box, float radius, Color color, float width)
{ public static bool segment_rect_intersection(Rect bounds, ref Vector2 p1, ref Vector2 p2)
Vector2 p1, p2, p3, p4, p5, p6, p7, p8; {
p1 = new Vector2(box.xMin + radius, box.yMin); float u1 = 0.0f, u2 = 1.0f, dx = p2.x - p1.x, dy;
p2 = new Vector2(box.xMax - radius, box.yMin);
p3 = new Vector2(box.xMax, box.yMin + radius); if (clip_test(-dx, p1.x - bounds.xMin, ref u1, ref u2))
p4 = new Vector2(box.xMax, box.yMax - radius); {
p5 = new Vector2(box.xMax - radius, box.yMax); if (clip_test(dx, bounds.xMax - p1.x, ref u1, ref u2))
p6 = new Vector2(box.xMin + radius, box.yMax); {
p7 = new Vector2(box.xMin, box.yMax - radius); dy = p2.y - p1.y;
p8 = new Vector2(box.xMin, box.yMin + radius); if (clip_test(-dy, p1.y - bounds.yMin, ref u1, ref u2))
{
DrawLine(p1, p2, color, width); if (clip_test(dy, bounds.yMax - p1.y, ref u1, ref u2))
DrawLine(p3, p4, color, width); {
DrawLine(p5, p6, color, width); if (u2 < 1.0)
DrawLine(p7, p8, color, width); {
p2.x = p1.x + u2 * dx;
Vector2 t1, t2; p2.y = p1.y + u2 * dy;
float halfRadius = radius / 2; }
t1 = new Vector2(p8.x, p8.y + halfRadius); if (u1 > 0.0)
t2 = new Vector2(p1.x - halfRadius, p1.y); {
DrawBezier(p8, t1, p1, t2, color, width); p1.x += u1 * dx;
p1.y += u1 * dy;
t1 = new Vector2(p2.x + halfRadius, p2.y); }
t2 = new Vector2(p3.x, p3.y - halfRadius); return true;
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); return false;
}
t1 = new Vector2(p6.x - halfRadius, p6.y);
t2 = new Vector2(p7.x, p7.y + halfRadius); public static void BeginGroup(Rect position)
DrawBezier(p6, t1, p7, t2, color, width); {
} clippingEnabled = true;
clippingBounds = new Rect(0, 0, position.width, position.height);
public static void DrawConnectingCurve(Vector2 start, Vector2 end, Color color, float width) GUI.BeginGroup(position);
{ }
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; public static void EndGroup()
Vector2 arrowPosB = arrowPosA; {
Vector2 arrowPosC = arrowPosA; 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);
}
Vector2 dir = (pB - pA).normalized; public static void EndScrollView()
{
arrowPosB.x += dir.y * arrowHeadSize; GUI.EndScrollView();
arrowPosB.y -= dir.x * arrowHeadSize; clippingBounds = new Rect(0, 0, Screen.width, Screen.height);
arrowPosB -= dir * arrowHeadSize; clippingEnabled = false;
}
arrowPosC.x -= dir.y * arrowHeadSize;
arrowPosC.y += dir.x * arrowHeadSize; public static void CreateMaterial()
arrowPosC -= dir * arrowHeadSize; {
if (lineMaterial != null)
DrawLine(arrowPosA, arrowPosB, color, 1.025f); return;
DrawLine(arrowPosA, arrowPosC, color, 1.025f);
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;
}
} }
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;
}
} }
Loading…
Cancel
Save