Skip to content

Instantly share code, notes, and snippets.

@popcron
Created April 30, 2023 20:18
Show Gist options
  • Save popcron/dc38a46a77ea87b5acc72da034519944 to your computer and use it in GitHub Desktop.
Save popcron/dc38a46a77ea87b5acc72da034519944 to your computer and use it in GitHub Desktop.
Can draw a circle/square with roundedness settings per each corner
#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