Created
April 30, 2023 20:18
-
-
Save popcron/dc38a46a77ea87b5acc72da034519944 to your computer and use it in GitHub Desktop.
Can draw a circle/square with roundedness settings per each corner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nullable enable | |
using System; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
namespace Game | |
{ | |
[ExecuteAlways] | |
public class BasicCircleImage : MaskableGraphic | |
{ | |
[SerializeField] | |
private int points = 8; | |
[SerializeField, Range(0f, 1f)] | |
private float roundednessTopLeft = 0.5f; | |
[SerializeField, Range(0f, 1f)] | |
private float roundednessTopRight = 0.5f; | |
[SerializeField, Range(0f, 1f)] | |
private float roundednessBottomLeft = 0.5f; | |
[SerializeField, Range(0f, 1f)] | |
private float roundednessBottomRight = 0.5f; | |
private float? lastRoundednessTopLeft; | |
private float? lastRoundednessTopRight; | |
private float? lastRoundednessBottomLeft; | |
private float? lastRoundednessBottomRight; | |
private readonly List<UIVertex> vertices = new(); | |
private readonly List<int> triangles = new(); | |
protected override void OnPopulateMesh(VertexHelper vh) | |
{ | |
vertices.Clear(); | |
triangles.Clear(); | |
Vector2 size = ((RectTransform)transform).rect.size * 0.5f; | |
vh.Clear(); | |
int points = this.points; | |
float angle = 90f / points; | |
Span<float> roundedness = stackalloc float[4] | |
{ | |
roundednessTopLeft, | |
roundednessTopRight, | |
roundednessBottomLeft, | |
roundednessBottomRight | |
}; | |
for (int q = 0; q < 4; q++) | |
{ | |
float r = roundedness[q]; | |
float cornerAngle = q * 90f; | |
Vector2 cornerDirection = new Vector2(Mathf.Sin(Mathf.Deg2Rad * (cornerAngle + 45f)), Mathf.Cos(Mathf.Deg2Rad * (cornerAngle + 45f))) * 1.414f; | |
for (int i = 0; i < points + 1; i++) | |
{ | |
float a = cornerAngle + (angle * i); | |
float x = Mathf.Sin(Mathf.Deg2Rad * a); | |
float y = Mathf.Cos(Mathf.Deg2Rad * a); | |
Vector2 position = new(x, y); | |
position = (position * r) + (cornerDirection * (1f - r)); | |
UIVertex vertex = new() | |
{ | |
position = position * size, | |
color = color, | |
uv0 = position | |
}; | |
vertices.Add(vertex); | |
} | |
} | |
for (int i = 0; i < vertices.Count - 2; i++) | |
{ | |
triangles.Add(0); | |
triangles.Add(i + 1); | |
triangles.Add(i + 2); | |
} | |
vh.AddUIVertexStream(vertices, triangles); | |
} | |
protected override void Reset() | |
{ | |
Vector2 size = ((RectTransform)transform).rect.size; | |
points = Mathf.Clamp((int)size.y, 3, 300); | |
} | |
private void Update() | |
{ | |
if (lastRoundednessTopLeft != roundednessTopLeft || lastRoundednessTopRight != roundednessTopRight || lastRoundednessBottomLeft != roundednessBottomLeft || lastRoundednessBottomRight != roundednessBottomRight) | |
{ | |
lastRoundednessTopLeft = roundednessTopLeft; | |
lastRoundednessTopRight = roundednessTopRight; | |
lastRoundednessBottomLeft = roundednessBottomLeft; | |
lastRoundednessBottomRight = roundednessBottomRight; | |
SetVerticesDirty(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment