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; } } }