2026-11-04 04:05:46 +00:00
|
|
|
|
using System.Collections.Generic;
|
2026-11-03 19:10:10 +00:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace TKS
|
|
|
|
|
|
{
|
2026-11-04 04:05:46 +00:00
|
|
|
|
/// <summary>아트 리소스 없이 쓰는 도형 스프라이트(원·링·얇은 링·도넛·사각). 프로토타입 전용.</summary>
|
2026-11-03 19:10:10 +00:00
|
|
|
|
public static class ProceduralSprites
|
|
|
|
|
|
{
|
|
|
|
|
|
static Sprite circle;
|
|
|
|
|
|
static Sprite ring;
|
2026-11-04 04:05:46 +00:00
|
|
|
|
static Sprite thinRing;
|
2026-11-03 19:10:10 +00:00
|
|
|
|
static Sprite square;
|
2026-11-04 04:05:46 +00:00
|
|
|
|
static readonly Dictionary<int, Sprite> donuts = new Dictionary<int, Sprite>();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>바깥 지름 1 월드 단위의 얇은 흰 링(두께 3 %) — 사거리 표시용.</summary>
|
|
|
|
|
|
public static Sprite ThinRing
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (thinRing == null) thinRing = MakeRing(256, 0.03f);
|
|
|
|
|
|
return thinRing;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>바깥 지름 1 · 안쪽 지름 innerFrac(0~1) 의 채워진 도넛 — 궁병 공격 가능 범위 표시용.</summary>
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2026-11-03 19:10:10 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>지름 1 월드 단위의 흰 원.</summary>
|
|
|
|
|
|
public static Sprite Circle
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (circle == null) circle = MakeCircle(128);
|
|
|
|
|
|
return circle;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>바깥 지름 1 월드 단위의 흰 링(두께 12 %).</summary>
|
|
|
|
|
|
public static Sprite Ring
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ring == null) ring = MakeRing(128, 0.12f);
|
|
|
|
|
|
return ring;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>1×1 월드 단위의 흰 사각형.</summary>
|
|
|
|
|
|
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<SpriteRenderer>();
|
|
|
|
|
|
sr.sprite = sprite;
|
|
|
|
|
|
sr.color = color;
|
|
|
|
|
|
sr.sortingOrder = sortingOrder;
|
|
|
|
|
|
go.transform.localScale = new Vector3(scale, scale, 1f);
|
|
|
|
|
|
return sr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|