ThreeKingdomsSlingshot/Assets/Scripts/Runtime/ProceduralSprites.cs

144 lines
5.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEngine;
namespace TKS
{
/// <summary>아트 리소스 없이 쓰는 도형 스프라이트(원·링·얇은 링·도넛·사각). 프로토타입 전용.</summary>
public static class ProceduralSprites
{
static Sprite circle;
static Sprite ring;
static Sprite thinRing;
static Sprite square;
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;
}
/// <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;
}
}
}