219 lines
7.8 KiB
C#
219 lines
7.8 KiB
C#
|
/// <summary>
|
||
|
/// Created by Freezy - ElicitIce.nl
|
||
|
/// Posted on Unity Forums http://forum.unity3d.com/threads/cut-corners-primative.359494/
|
||
|
///
|
||
|
/// Free for any use and alteration, source code may not be sold without my permission.
|
||
|
/// If you make improvements on this script please share them with the community.
|
||
|
///
|
||
|
///
|
||
|
/// Here is a script that will take a rectangular TransformRect and cut off some corners based on the corner size.
|
||
|
/// This is great for when you need a quick and easy non-square panel/image.
|
||
|
/// Enjoy!
|
||
|
/// It adds an additional square if the relevant side has a corner cut, it then offsets the ends to simulate a cut corner.
|
||
|
/// UVs are being set, but might be skewed when a texture is applied.
|
||
|
/// You could hide the additional colors by using the following:
|
||
|
/// http://rumorgames.com/hide-in-inspector/
|
||
|
///
|
||
|
/// </summary>
|
||
|
|
||
|
namespace UnityEngine.UI.Extensions
|
||
|
{
|
||
|
[AddComponentMenu("UI/Extensions/Primitives/Cut Corners")]
|
||
|
public class UICornerCut : UIPrimitiveBase
|
||
|
{
|
||
|
public Vector2 cornerSize = new Vector2(16, 16);
|
||
|
|
||
|
[Header("Corners to cut")]
|
||
|
[SerializeField]
|
||
|
private bool m_cutUL = true;
|
||
|
[SerializeField]
|
||
|
private bool m_cutUR;
|
||
|
[SerializeField]
|
||
|
private bool m_cutLL;
|
||
|
[SerializeField]
|
||
|
private bool m_cutLR;
|
||
|
|
||
|
[Tooltip("Up-Down colors become Left-Right colors")]
|
||
|
[SerializeField]
|
||
|
private bool m_makeColumns;
|
||
|
|
||
|
[Header("Color the cut bars differently")]
|
||
|
[SerializeField]
|
||
|
private bool m_useColorUp;
|
||
|
[SerializeField]
|
||
|
private Color32 m_colorUp;
|
||
|
[SerializeField]
|
||
|
private bool m_useColorDown;
|
||
|
[SerializeField]
|
||
|
private Color32 m_colorDown;
|
||
|
|
||
|
public bool CutUL
|
||
|
{
|
||
|
get { return m_cutUL; }
|
||
|
set { m_cutUL = value; SetAllDirty(); }
|
||
|
}
|
||
|
|
||
|
public bool CutUR
|
||
|
{
|
||
|
get { return m_cutUR; }
|
||
|
set { m_cutUR = value; SetAllDirty(); }
|
||
|
}
|
||
|
|
||
|
public bool CutLL
|
||
|
{
|
||
|
get { return m_cutLL; }
|
||
|
set { m_cutLL = value; SetAllDirty(); }
|
||
|
}
|
||
|
|
||
|
public bool CutLR
|
||
|
{
|
||
|
get { return m_cutLR; }
|
||
|
set { m_cutLR = value; SetAllDirty(); }
|
||
|
}
|
||
|
|
||
|
public bool MakeColumns
|
||
|
{
|
||
|
get { return m_makeColumns; }
|
||
|
set { m_makeColumns = value; SetAllDirty(); }
|
||
|
}
|
||
|
|
||
|
public bool UseColorUp
|
||
|
{
|
||
|
get { return m_useColorUp; }
|
||
|
set { m_useColorUp = value; }
|
||
|
}
|
||
|
|
||
|
public Color32 ColorUp
|
||
|
{
|
||
|
get { return m_colorUp; }
|
||
|
set { m_colorUp = value; }
|
||
|
}
|
||
|
|
||
|
public bool UseColorDown
|
||
|
{
|
||
|
get { return m_useColorDown; }
|
||
|
set { m_useColorDown = value; }
|
||
|
}
|
||
|
|
||
|
public Color32 ColorDown
|
||
|
{
|
||
|
get { return m_colorDown; }
|
||
|
set { m_colorDown = value; }
|
||
|
}
|
||
|
|
||
|
protected override void OnPopulateMesh(VertexHelper vh)
|
||
|
{
|
||
|
var rect = rectTransform.rect;
|
||
|
var rectNew = rect;
|
||
|
|
||
|
Color32 color32 = color;
|
||
|
bool up = m_cutUL | m_cutUR;
|
||
|
bool down = m_cutLL | m_cutLR;
|
||
|
bool left = m_cutLL | m_cutUL;
|
||
|
bool right = m_cutLR | m_cutUR;
|
||
|
bool any = up | down;
|
||
|
|
||
|
if (any && cornerSize.sqrMagnitude > 0)
|
||
|
{
|
||
|
|
||
|
//nibble off the sides
|
||
|
vh.Clear();
|
||
|
if (left)
|
||
|
rectNew.xMin += cornerSize.x;
|
||
|
if (down)
|
||
|
rectNew.yMin += cornerSize.y;
|
||
|
if (up)
|
||
|
rectNew.yMax -= cornerSize.y;
|
||
|
if (right)
|
||
|
rectNew.xMax -= cornerSize.x;
|
||
|
|
||
|
//add two squares to the main square
|
||
|
Vector2 ul, ur, ll, lr;
|
||
|
|
||
|
if (m_makeColumns)
|
||
|
{
|
||
|
ul = new Vector2(rect.xMin, m_cutUL ? rectNew.yMax : rect.yMax);
|
||
|
ur = new Vector2(rect.xMax, m_cutUR ? rectNew.yMax : rect.yMax);
|
||
|
ll = new Vector2(rect.xMin, m_cutLL ? rectNew.yMin : rect.yMin);
|
||
|
lr = new Vector2(rect.xMax, m_cutLR ? rectNew.yMin : rect.yMin);
|
||
|
|
||
|
if (left)
|
||
|
AddSquare(
|
||
|
ll, ul,
|
||
|
new Vector2(rectNew.xMin, rect.yMax),
|
||
|
new Vector2(rectNew.xMin, rect.yMin),
|
||
|
rect, m_useColorUp ? m_colorUp : color32, vh);
|
||
|
if (right)
|
||
|
AddSquare(
|
||
|
ur, lr,
|
||
|
new Vector2(rectNew.xMax, rect.yMin),
|
||
|
new Vector2(rectNew.xMax, rect.yMax),
|
||
|
rect, m_useColorDown ? m_colorDown : color32, vh);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ul = new Vector2(m_cutUL ? rectNew.xMin : rect.xMin, rect.yMax);
|
||
|
ur = new Vector2(m_cutUR ? rectNew.xMax : rect.xMax, rect.yMax);
|
||
|
ll = new Vector2(m_cutLL ? rectNew.xMin : rect.xMin, rect.yMin);
|
||
|
lr = new Vector2(m_cutLR ? rectNew.xMax : rect.xMax, rect.yMin);
|
||
|
if (down)
|
||
|
AddSquare(
|
||
|
lr, ll,
|
||
|
new Vector2(rect.xMin, rectNew.yMin),
|
||
|
new Vector2(rect.xMax, rectNew.yMin),
|
||
|
rect, m_useColorDown ? m_colorDown : color32, vh);
|
||
|
if (up)
|
||
|
AddSquare(
|
||
|
ul, ur,
|
||
|
new Vector2(rect.xMax, rectNew.yMax),
|
||
|
new Vector2(rect.xMin, rectNew.yMax),
|
||
|
rect, m_useColorUp ? m_colorUp : color32, vh);
|
||
|
}
|
||
|
|
||
|
//center
|
||
|
if (m_makeColumns)
|
||
|
AddSquare(new Rect(rectNew.xMin, rect.yMin, rectNew.width, rect.height), rect, color32, vh);
|
||
|
else
|
||
|
AddSquare(new Rect(rect.xMin, rectNew.yMin, rect.width, rectNew.height), rect, color32, vh);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void AddSquare(Rect rect, Rect rectUV, Color32 color32, VertexHelper vh) {
|
||
|
int v0 = AddVert(rect.xMin, rect.yMin, rectUV, color32, vh);
|
||
|
int v1 = AddVert(rect.xMin, rect.yMax, rectUV, color32, vh);
|
||
|
int v2 = AddVert(rect.xMax, rect.yMax, rectUV, color32, vh);
|
||
|
int v3 = AddVert(rect.xMax, rect.yMin, rectUV, color32, vh);
|
||
|
|
||
|
vh.AddTriangle(v0, v1, v2);
|
||
|
vh.AddTriangle(v2, v3, v0);
|
||
|
}
|
||
|
|
||
|
private static void AddSquare(Vector2 a, Vector2 b, Vector2 c, Vector2 d, Rect rectUV, Color32 color32, VertexHelper vh) {
|
||
|
int v0 = AddVert(a.x, a.y, rectUV, color32, vh);
|
||
|
int v1 = AddVert(b.x, b.y, rectUV, color32, vh);
|
||
|
int v2 = AddVert(c.x, c.y, rectUV, color32, vh);
|
||
|
int v3 = AddVert(d.x, d.y, rectUV, color32, vh);
|
||
|
|
||
|
vh.AddTriangle(v0, v1, v2);
|
||
|
vh.AddTriangle(v2, v3, v0);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Auto UV handler within the assigned area
|
||
|
/// </summary>
|
||
|
/// <param name="x"></param>
|
||
|
/// <param name="y"></param>
|
||
|
/// <param name="area"></param>
|
||
|
/// <param name="color32"></param>
|
||
|
/// <param name="vh"></param>
|
||
|
private static int AddVert(float x, float y, Rect area, Color32 color32, VertexHelper vh) {
|
||
|
var uv = new Vector2(
|
||
|
Mathf.InverseLerp(area.xMin, area.xMax, x),
|
||
|
Mathf.InverseLerp(area.yMin, area.yMax, y)
|
||
|
);
|
||
|
vh.AddVert(new Vector3(x, y), color32, uv);
|
||
|
return vh.currentVertCount - 1;
|
||
|
}
|
||
|
}
|
||
|
}
|