VSClone/Assets/Scripts/View/Skin.cs

125 lines
7.5 KiB
C#

using System.Collections.Generic;
using UnityEngine;
// UI 스킨 — Layer Lab 「GUI Pro-SuperCasual」 스프라이트(Resources/UI/GUIPro · 9분할 border 는 .meta 그대로)
// 그림이 없으면(폴더 누락) 코드 그림(Art)으로 되돌아간다 · 아이콘 이름 → 팩 아이콘 표 = IconMap
namespace VS.View
{
public static class Skin
{
const string Dir = "UI/GUIPro/";
static readonly Dictionary<string, Sprite> cache = new Dictionary<string, Sprite>();
static int available = -1;
public static bool On
{
get
{
if (available < 0) available = Resources.Load<Sprite>(Dir + "BorderFrame_Round24") != null ? 1 : 0;
return available == 1;
}
}
/// 팩 스프라이트(없으면 null)
public static Sprite S(string name)
{
if (string.IsNullOrEmpty(name)) return null;
if (cache.TryGetValue(name, out var s)) return s;
s = Resources.Load<Sprite>(Dir + name);
cache[name] = s;
return s;
}
// ---- 기본 모양 (흰 몸 + 남색 테두리 · 색은 Image.color 로) ----
public static Sprite Round => S("BorderFrame_Round24") ?? Art.Round; // 둥근 판
public static Sprite RoundSoft => S("BasicFrame_Round20") ?? Art.Round; // 테두리 없는 둥근 판
public static Sprite Pill => S("BasicFrame_Oval50") ?? Art.Pill; // 알약
public static Sprite Circle => S("BorderFrame_Circle78") ?? Art.Circle; // 테두리 원
public static Sprite CirclePlain => S("Alert_Circle_s_Bg") ?? Art.Circle; // 테두리 없는 원
public static Sprite Dark => S("Button_Round03_Dark") ?? Art.Round; // 남색 네모 버튼(로비 사이드 버튼)
public static Sprite BottomBar => S("Popup_FullWidth_Dark") ?? Art.Square; // 아래 띠(윗선 밝음)
public static Sprite TabBar => S("Menu_BottomBtn_Bg") ?? Art.Square;
public static Sprite TabFocus => S("Menu_BottomBtn_TabFocus") ?? Art.Round;
public static Sprite Pattern => S("Pattern01");
public static Sprite Counter => S("ResourceBar_Single_Bg") ?? Art.Pill; // 상단 자원 칸
public static Sprite CounterBtn => S("ResourceBar_Single_Btn_Yellow1") ?? Art.Round;
public static Sprite Plus => S("ResourceBar_White_Icon1");
public static Sprite ProfileFrame => S("ProfileFrame01_m~s_Bg") ?? Art.Round;
public static Sprite ProfileInner => S("ProfileFrame01_m~s_Inner") ?? Art.Round;
public static Sprite PopupBg => S("Popup02~09_Topber_White_Bg") ?? Art.Round;
public static Sprite PopupTop => S("Popup02~09_Topber_White_BgTop");
public static Sprite PopupTopLight => S("Popup02~09_Topber_White_BgTopLight");
public static Sprite PopupPlain => S("Popup01_Basic_White_Bg") ?? Art.Round;
public static Sprite BarBg => S("Slider_Basic01_Bg_White1") ?? Art.Round;
public static Sprite BarFill => Art.Pill; // 팩 채움 그림은 오른쪽 끝이 어두워 평평한 코드 알약 사용
public static readonly Color CounterTint = new Color(0.17f, 0.19f, 0.32f, 0.95f); // 흰 자원 칸 → 남색
public static Sprite BarBgThick => S("Slider_Basic04_Bg") ?? Art.Pill;
public static Sprite HpBg => S("Slider_Play01_Bg") ?? Art.Round;
public static Sprite HpFill => S("Slider_Play01_Fill") ?? Art.Pill;
public static Sprite CardOn => S("ItemFrame02_Single_Blue") ?? Art.Round;
public static Sprite CardOff => S("ItemFrame02_Single_Gray") ?? Art.Round;
public static Sprite CardWhite => S("ItemFrame02_Single_OffWhite") ?? Art.Round;
public static Sprite Label => S("Label_Parallelogram_Blue") ?? Art.Pill;
public static Sprite DotBorder => S("Alert_Dot_Border");
public static Sprite ManaGem => S("ResourceBar_Single_Icon_Gem");
public static Sprite Gem => S("Icon_Gem");
public static Sprite Toast => S("BasicFrame_Round20") ?? Art.Round;
/// 제목 리본 (파랑 · 노랑 · 빨강 …)
public static Sprite Ribbon(string color) => S("Title_Ribbon01_" + color) ?? Art.Round;
// ---- 버튼: 팔레트 색 → 색이 구워진 버튼 그림 ----
static readonly (Color c, string name)[] BtnColors =
{
(Pal.Blue, "Blue"), (Pal.Green, "Green"), (Pal.Yellow, "Yellow"), (Pal.Orange, "Yellow"), (Pal.Red, "Red"),
(Pal.Purple, "Purple"), (Pal.PurpleDark, "Purple"), (Pal.Pink, "Pink"), (Pal.PinkDark, "Pink"), (Pal.Gray, "Gray"),
(new Color32(84, 170, 255, 255), "Blue"), (new Color32(90, 160, 230, 255), "Blue"), (new Color32(110, 120, 140, 255), "Gray"),
(new Color32(150, 146, 170, 255), "Gray"), (new Color32(70, 60, 80, 255), "DarkGray"), (new Color32(84, 64, 120, 255), "DarkGray"),
(new Color32(60, 40, 90, 255), "DarkGray"), (Color.white, "White_Bg"), (new Color32(90, 220, 200, 255), "Mint"), (new Color32(90, 200, 255, 255), "Sky"),
};
/// 색에 가장 가까운 버튼 그림 이름(색 접미사)
public static string ButtonColorName(Color c)
{
float best = float.MaxValue; string name = "Blue";
foreach (var (bc, n) in BtnColors)
{
float d = (bc.r - c.r) * (bc.r - c.r) + (bc.g - c.g) * (bc.g - c.g) + (bc.b - c.b) * (bc.b - c.b);
if (d < best) { best = d; name = n; }
}
return name;
}
/// 글자 버튼 그림 (큰 = Button01_l · 작은 = Button01_s). 팩이 없으면 null → 호출자가 Art.Round + 색으로
public static Sprite Button(Color c, bool small = false)
{
if (!On) return null;
string n = ButtonColorName(c);
return S((small ? "Button01_s_" : "Button01_l_") + n) ?? S((small ? "Button01_s_" : "Button01_l_") + "Blue");
}
// ---- 아이콘: 코드 그림 이름 → 팩 아이콘 ----
static readonly Dictionary<string, string> IconMap = new Dictionary<string, string>
{
{ "coin", "ItemIcon_Money_Coin" }, { "ticket", "ItemIcon_Ticket_Red" }, { "heart", "Icon_Heart" }, { "follower", "ItemIcon_Friend" },
{ "view", "Icon_Face" }, { "house", "Icon_Castle" }, { "closet", "Icon_Top" }, { "skill", "ItemIcon_Book_1_Purple" },
{ "x2", "ItemIcon_Heart_Red" }, { "auto", "ItemIcon_Energy_Blue" }, { "gear", "Icon_Setting" }, { "gift", "ItemIcon_Gift_Red" },
{ "task", "ItemIcon_MemoPad" }, { "afk", "Icon_Timer" }, { "lock", "Icon_Lock01_l" }, { "up", "Slider_Level02_Icon_Up_Green" },
{ "star", "ItemIcon_Star_Gold" }, { "fire", "Icon_Fire01" }, { "chat", "Icon_Chat" }, { "shop", "ItemIcon_Shop" },
{ "pk", "Icon_Sword01" }, { "calendar", "ItemIcon_Calendar" }, { "close", "Icon_Close01" }, { "check", "Icon_Check01" },
{ "video", "ItemIcon_Video" }, { "trophy", "ItemIcon_Trophy_Gold" }, { "gem", "Icon_Gem" }, { "crown", "Icon_Crown" },
{ "battle", "ItemIcon_Battle" }, { "chest", "ItemIcon_Chest_Gold" }, { "key", "ItemIcon_Key_Gold" }, { "map", "ItemIcon_Map" },
};
public static Sprite Icon(string name)
{
if (On && IconMap.TryGetValue(name, out var pack))
{
var s = S(pack);
if (s != null) return s;
}
return Art.Icon(name);
}
}
}