using System; using System.Collections.Generic; using UnityEngine; namespace TKS { /// /// UI 테마(PD #1100 UI 리뉴얼 · 2026-11-06) — 색 팔레트 · 9-slice 부품(스킨) · 아이콘 id → 스프라이트 치환 테이블 · 제목 폰트. /// SOT = Assets/Data/UI/ui_theme.csv → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset(에디터 UIThemeImporter). /// 스킨·아이콘은 팩(Layer Lab GUI Pro-SuperCasual · Assets/UI/GUIPro) 기본 + 신규 제작 납품(Assets/UI/Samguk/**/<id>.png)이 있으면 그것으로 치환. /// 화면 코드는 id 로만 묻는다(스프라이트 경로를 코드에 쓰지 않는다 · C45). /// [CreateAssetMenu(menuName = "TKS/UI Theme")] public class UITheme : ScriptableObject { public const string ResourcePath = "UI/UITheme"; [Serializable] public class ColorEntry { public string id; public Color color = Color.white; } [Serializable] public class SkinEntry { public string id; /// 팩 바탕(흰 계열 = 호출 색으로 틴트). public Sprite pack; /// 신규 제작 치환(있으면 pack 대신). public Sprite samguk; /// 위 덮개(광택·글리프 · 틴트 안 함). public Sprite overlay; /// 9-slice 배율(Image.pixelsPerUnitMultiplier · 클수록 테두리가 얇다). public float ppu = 1f; /// 덮개 안쪽 여백(px · 왼 · 위 · 오 · 아래). public Vector4 inset; /// 덮개 불투명도. public float overlayAlpha = 1f; public Sprite Sprite { get { return samguk != null ? samguk : pack; } } } [Serializable] public class IconEntry { public string id; public Sprite pack; public Sprite samguk; /// 표시 색(흰 실루엣 아이콘용 · 기본 흰색 = 원색 그대로). public Color tint = Color.white; public Sprite Sprite { get { return samguk != null ? samguk : pack; } } } public List colors = new List(); public List skins = new List(); public List icons = new List(); /// 제목·숫자 강조(Sen-ExtraBold · 한글 = 임포터 폴백 Malgun Gothic · PD 결정 전). public Font titleFont; Dictionary colorMap; Dictionary skinMap; Dictionary iconMap; static UITheme current; static bool tried; /// Resources/UI/UITheme(없으면 null = 기존 도형 UI 로 동작). public static UITheme Current { get { if (current == null && !tried) { tried = true; current = Resources.Load(ResourcePath); } return current; } } /// 테마 교체(임포트 뒤 · 테스트) — null = 다시 Resources 에서 읽음. public static void Use(UITheme t) { current = t; tried = t != null; if (t != null) t.Rebuild(); } public void Rebuild() { colorMap = new Dictionary(); foreach (var c in colors) if (c != null && !string.IsNullOrEmpty(c.id)) colorMap[c.id] = c; skinMap = new Dictionary(); foreach (var s in skins) if (s != null && !string.IsNullOrEmpty(s.id)) skinMap[s.id] = s; iconMap = new Dictionary(); foreach (var i in icons) if (i != null && !string.IsNullOrEmpty(i.id)) iconMap[i.id] = i; } void OnEnable() { colorMap = null; } void Ensure() { if (colorMap == null || skinMap == null || iconMap == null) Rebuild(); } public bool TryColor(string id, out Color c) { Ensure(); ColorEntry e; if (id != null && colorMap.TryGetValue(id, out e)) { c = e.color; return true; } c = Color.white; return false; } public SkinEntry Skin(string id) { Ensure(); SkinEntry e; return id != null && skinMap.TryGetValue(id, out e) && e.Sprite != null ? e : null; } public IconEntry IconEntryOf(string id) { Ensure(); IconEntry e; return id != null && iconMap.TryGetValue(id, out e) && e.Sprite != null ? e : null; } public Sprite Icon(string id) { var e = IconEntryOf(id); return e != null ? e.Sprite : null; } } }