using System.Collections.Generic;
using UnityEngine;
namespace TKS
{
/// 아트 리소스 없이 쓰는 도형 스프라이트(원·링·얇은 링·도넛·사각). 프로토타입 전용.
public static class ProceduralSprites
{
static Sprite circle;
static Sprite ring;
static Sprite thinRing;
static Sprite square;
static readonly Dictionary donuts = new Dictionary();
/// 바깥 지름 1 월드 단위의 얇은 흰 링(두께 3 %) — 사거리 표시용.
public static Sprite ThinRing
{
get
{
if (thinRing == null) thinRing = MakeRing(256, 0.03f);
return thinRing;
}
}
/// 바깥 지름 1 · 안쪽 지름 innerFrac(0~1) 의 채워진 도넛 — 궁병 공격 가능 범위 표시용.
public static Sprite Donut(float innerFrac)
{
int key = Mathf.RoundToInt(Mathf.Clamp01(innerFrac) * 1000f);
Sprite s;
if (!donuts.TryGetValue(key, out s))
{
s = MakeRing(256, 1f - key / 1000f);
donuts[key] = s;
}
return s;
}
/// 지름 1 월드 단위의 흰 원.
public static Sprite Circle
{
get
{
if (circle == null) circle = MakeCircle(128);
return circle;
}
}
/// 바깥 지름 1 월드 단위의 흰 링(두께 12 %).
public static Sprite Ring
{
get
{
if (ring == null) ring = MakeRing(128, 0.12f);
return ring;
}
}
/// 1×1 월드 단위의 흰 사각형.
public static Sprite Square
{
get
{
if (square == null)
{
var tex = new Texture2D(4, 4, TextureFormat.RGBA32, false);
var px = new Color[16];
for (int i = 0; i < px.Length; i++) px[i] = Color.white;
tex.SetPixels(px);
tex.Apply();
tex.hideFlags = HideFlags.DontSave;
square = Sprite.Create(tex, new Rect(0, 0, 4, 4), new Vector2(0.5f, 0.5f), 4f);
square.hideFlags = HideFlags.DontSave;
}
return square;
}
}
static Sprite MakeCircle(int size)
{
var tex = new Texture2D(size, size, TextureFormat.RGBA32, false);
tex.wrapMode = TextureWrapMode.Clamp;
tex.filterMode = FilterMode.Bilinear;
float half = size * 0.5f;
var px = new Color[size * size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float dx = x + 0.5f - half;
float dy = y + 0.5f - half;
float d = Mathf.Sqrt(dx * dx + dy * dy);
float a = Mathf.Clamp01(half - d); // 1 px 안티앨리어싱
px[y * size + x] = new Color(1f, 1f, 1f, a);
}
}
tex.SetPixels(px);
tex.Apply();
tex.hideFlags = HideFlags.DontSave;
var s = Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), size);
s.hideFlags = HideFlags.DontSave;
return s;
}
static Sprite MakeRing(int size, float thicknessFrac)
{
var tex = new Texture2D(size, size, TextureFormat.RGBA32, false);
tex.wrapMode = TextureWrapMode.Clamp;
tex.filterMode = FilterMode.Bilinear;
float half = size * 0.5f;
float inner = half * (1f - thicknessFrac);
var px = new Color[size * size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float dx = x + 0.5f - half;
float dy = y + 0.5f - half;
float d = Mathf.Sqrt(dx * dx + dy * dy);
float a = Mathf.Clamp01(half - d) * Mathf.Clamp01(d - inner);
px[y * size + x] = new Color(1f, 1f, 1f, a);
}
}
tex.SetPixels(px);
tex.Apply();
tex.hideFlags = HideFlags.DontSave;
var s = Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), size);
s.hideFlags = HideFlags.DontSave;
return s;
}
public static SpriteRenderer NewSprite(Transform parent, string name, Sprite sprite, Color color, float scale, int sortingOrder)
{
var go = new GameObject(name);
go.transform.SetParent(parent, false);
var sr = go.AddComponent();
sr.sprite = sprite;
sr.color = color;
sr.sortingOrder = sortingOrder;
go.transform.localScale = new Vector3(scale, scale, 1f);
return sr;
}
}
}