병과 심볼 = 평면(입체감 제거)(#1104 · PD 2026-11-09 「병종 심볼에 입체감이 느껴지지 않도록」)

- 심볼 그림 = 검은 바깥 테두리 + 흰 채움만(원본 안쪽 선 = 베벨·명암처럼 보여 뺌 · Tools/class_symbols.py --inner-lum 기본 0)
- 모든 자리에서 심볼 그림자 제거(목록·도감 카드 · 영웅 상세 이름 띠·스킬 행 · 스테이지 팝업 · 전투 HUD)
- 확인 캡처 = 영웅 목록만(-uiOnly) · 테스트 118/118 · console error 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-09 20:20:15 +09:00
parent d5a3b1376d
commit 074882b5a1
9 changed files with 8 additions and 11 deletions

View File

@ -50,8 +50,7 @@ namespace TKS.OutGame
// 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09) // 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09)
var ring = UiKit.Rect("Type", t, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(142f, -12f), new Vector2(52f, 52f)); var ring = UiKit.Rect("Type", t, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(142f, -12f), new Vector2(52f, 52f));
var cls = UiKit.Icon(ring, UiKit.TypeSymbolId(h.type), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 50f); var cls = UiKit.Icon(ring, UiKit.TypeSymbolId(h.type), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 50f);
if (cls != null) UiKit.DropShadow(cls, 2f); if (cls == null) UiKit.Title(UiKit.FillLabel(ring, UnitTypeInfo.Mark(h.type), 26, UiKit.White), true);
else UiKit.Title(UiKit.FillLabel(ring, UnitTypeInfo.Mark(h.type), 26, UiKit.White), true);
if (owned) if (owned)
{ {
var badge = UiKit.Icon(t, "lv_badge_s", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(202f, -8f), 56f); var badge = UiKit.Icon(t, "lv_badge_s", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(202f, -8f), 56f);
@ -180,8 +179,7 @@ namespace TKS.OutGame
// 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09 「심볼은 배경 프레임 없이 단색」) // 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09 「심볼은 배경 프레임 없이 단색」)
var role = UiKit.Rect("Role", t, new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-42f, -42f), new Vector2(60f, 60f)); var role = UiKit.Rect("Role", t, new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-42f, -42f), new Vector2(60f, 60f));
var sym = UiKit.Icon(role, UiKit.TypeSymbolId(h.type), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 60f); var sym = UiKit.Icon(role, UiKit.TypeSymbolId(h.type), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 60f);
if (sym != null) UiKit.DropShadow(sym, 3f); if (sym == null) UiKit.Title(UiKit.FillLabel(role, UnitTypeInfo.Mark(h.type), 28, UiKit.White), true);
else UiKit.Title(UiKit.FillLabel(role, UnitTypeInfo.Mark(h.type), 28, UiKit.White), true);
if (s.CanGrowAny(h.id)) UiKit.Icon(t, "new_dot", new Vector2(0f, 0f), new Vector2(0.5f, 0.5f), new Vector2(64f, 70f), 30f); // 성장 가능 = 레벨 배지 오른쪽 위 if (s.CanGrowAny(h.id)) UiKit.Icon(t, "new_dot", new Vector2(0f, 0f), new Vector2(0.5f, 0.5f), new Vector2(64f, 70f), 30f); // 성장 가능 = 레벨 배지 오른쪽 위
return cell; return cell;
} }
@ -590,7 +588,7 @@ namespace TKS.OutGame
bandImg = Spr(body, "NameBand", "card", 24f, 776f, 1032f, 114f, "white"); bandImg = Spr(body, "NameBand", "card", 24f, 776f, 1032f, 114f, "white");
Spr(body, "BandLight", "band_light", 40f, 782f, 1000f, 12f, "band_light"); Spr(body, "BandLight", "band_light", 40f, 782f, 1000f, 12f, "band_light");
factionRoot = UiKit.At(body, "Faction", 44f, 789f, 88f, 88f); // 진영 원 배지 자리(PD 2026-11-09 · 구 세력 깃발) factionRoot = UiKit.At(body, "Faction", 44f, 789f, 88f, 88f); // 진영 원 배지 자리(PD 2026-11-09 · 구 세력 깃발)
clsIcon = Ico(body, null, 140f, 794f, 78f, 78f, 3f); // 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09) clsIcon = Ico(body, null, 140f, 794f, 78f, 78f); // 병과 = 평면 심볼만(배경 틀 · 그림자 없음 · PD 2026-11-09)
paraImg = Spr(body, "Grade", "para_green", 232f, 805f, 96f, 56f, "white"); paraImg = Spr(body, "Grade", "para_green", 232f, 805f, 96f, 56f, "white");
gradeText = Txt(body, "", 232f, 811f, 38, "white", TextAnchor.MiddleCenter, 96f); gradeText = Txt(body, "", 232f, 811f, 38, "white", TextAnchor.MiddleCenter, 96f);
nameText = Txt(body, "", 344f, 797f, 66, "white"); nameText = Txt(body, "", 344f, 797f, 66, "white");
@ -614,7 +612,7 @@ namespace TKS.OutGame
skLv[i] = Txt(lc.transform, "", 0f, 9f, 26, "white", TextAnchor.MiddleCenter, 112f, true, 3f); skLv[i] = Txt(lc.transform, "", 0f, 9f, 26, "white", TextAnchor.MiddleCenter, 112f, true, 3f);
rowImg[i] = Spr(body, "SkillRow" + i, "panel12", 44f, y, 992f, 146f, "white"); rowImg[i] = Spr(body, "SkillRow" + i, "panel12", 44f, y, 992f, 146f, "white");
skFrame[i] = Ico(body, null, 58f, y + 10f, 126f, 126f, 4f); skFrame[i] = Ico(body, null, 58f, y + 10f, 126f, 126f, 4f);
skCls[i] = Ico(body, null, 80f, y + 32f, 82f, 82f, 3f); skCls[i] = Ico(body, null, 80f, y + 32f, 82f, 82f);
skName[i] = Txt(body, "", 200f, y + 18f, 42, "white"); skName[i] = Txt(body, "", 200f, y + 18f, 42, "white");
skHanja[i] = Txt(body, "", 200f, y + 30f, 28, "white", TextAnchor.MiddleLeft, 0f, false, 0f, false); skHanja[i] = Txt(body, "", 200f, y + 30f, 28, "white", TextAnchor.MiddleLeft, 0f, false, 0f, false);
skDesc[i] = Desc(body, 200f, y + 74f, 600f); skDesc[i] = Desc(body, 200f, y + 74f, 600f);

View File

@ -793,7 +793,6 @@ namespace TKS.OutGame
float cx = ex + k * Ew + 44f; float cx = ex + k * Ew + 44f;
var circ = UiKit.Rect("Type" + k, field, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(cx, -y - 94f), new Vector2(80f, 80f)); var circ = UiKit.Rect("Type" + k, field, new Vector2(0f, 1f), new Vector2(0.5f, 0.5f), new Vector2(cx, -y - 94f), new Vector2(80f, 80f));
var ti = UiKit.Icon(circ, UiKit.TypeSymbolId(ut), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 76f); // 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09) var ti = UiKit.Icon(circ, UiKit.TypeSymbolId(ut), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 76f); // 병과 = 단색 심볼만(배경 틀 없음 · PD 2026-11-09)
if (ti != null) UiKit.DropShadow(ti, 2f);
var n = UiKit.Title(UiKit.Label(field, "x" + counts[kinds[k]], 36, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(cx + 50f, -y - 94f), new Vector2(100f, 50f)), true); var n = UiKit.Title(UiKit.Label(field, "x" + counts[kinds[k]], 36, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(cx + 50f, -y - 94f), new Vector2(100f, 50f)), true);
n.horizontalOverflow = HorizontalWrapMode.Overflow; n.horizontalOverflow = HorizontalWrapMode.Overflow;
} }

View File

@ -223,7 +223,6 @@ namespace TKS
typeRing = OutGame.UiKit.Skin(OutGame.UiKit.At(unitBody, "TypeRing", 188f, 20f, 52f, 52f), "circle_frame", Color.white); typeRing = OutGame.UiKit.Skin(OutGame.UiKit.At(unitBody, "TypeRing", 188f, 20f, 52f, 52f), "circle_frame", Color.white);
typeRing.enabled = false; typeRing.enabled = false;
typeIcon = OutGame.UiKit.Icon(typeRing.transform, OutGame.UiKit.TypeSymbolId(UnitType.Infantry), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 52f); typeIcon = OutGame.UiKit.Icon(typeRing.transform, OutGame.UiKit.TypeSymbolId(UnitType.Infantry), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 52f);
if (typeIcon != null) OutGame.UiKit.DropShadow(typeIcon, 2f);
nameText = OutGame.UiKit.Title(OutGame.UiKit.Label(unitBody, "", 36, Color.white, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(250f, -18f), new Vector2(300f, 56f)), true); nameText = OutGame.UiKit.Title(OutGame.UiKit.Label(unitBody, "", 36, Color.white, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(250f, -18f), new Vector2(300f, 56f)), true);
nameText.horizontalOverflow = HorizontalWrapMode.Overflow; nameText.horizontalOverflow = HorizontalWrapMode.Overflow;
stateText = OutGame.UiKit.Label(unitBody, "", 24, soft, TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-20f, -22f), new Vector2(220f, 48f), false); stateText = OutGame.UiKit.Label(unitBody, "", 24, soft, TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-20f, -22f), new Vector2(220f, 48f), false);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -2,7 +2,7 @@
새로 그리지 않는다 — 확정 납품 메달 아이콘(Assets/UI/Samguk/class/cls_<병과>.png)을 만들 때 쓴 투명 바탕 사물 그림 새로 그리지 않는다 — 확정 납품 메달 아이콘(Assets/UI/Samguk/class/cls_<병과>.png)을 만들 때 쓴 투명 바탕 사물 그림
(아트 R&D `C:/ArtRnD/samguk_ui/_work/class_symbol/rgba/cls_<병과>_s21A_rgba.png` · picked_auto.json = seed 21)의 투명도 = 형태. (아트 R&D `C:/ArtRnD/samguk_ui/_work/class_symbol/rgba/cls_<병과>_s21A_rgba.png` · picked_auto.json = seed 21)의 투명도 = 형태.
기본 = 검은 선(바깥 테두리 + 원본의 진한 안쪽 선) + 그 안쪽 흰 채움(PD 2026-11-09 「배경 프레임 없이 · 검은 선 안쪽은 흰색」) · --mono = 단색(채움 한 색 · 안쪽 선 = 뚫린 선). 기본 = 검은 바깥 테두리 + 그 안쪽 흰 채움 · 안쪽 선 없음(PD 2026-11-09 「배경 프레임 없이 · 검은 선 안쪽은 흰색 · 입체감이 느껴지지 않도록」 · --inner-lum 40 = 원본 안쪽 선 남김) · --mono = 단색(채움 한 색 · 안쪽 선 = 뚫린 선).
실행: <ComfyUI venv python> -I -B Tools/class_symbols.py [--src <rgba 폴더>] [--fill #RRGGBB] [--line #RRGGBB] [--out Assets/UI/Symbols] [--preview <png>] 실행: <ComfyUI venv python> -I -B Tools/class_symbols.py [--src <rgba 폴더>] [--fill #RRGGBB] [--line #RRGGBB] [--out Assets/UI/Symbols] [--preview <png>]
출력 = <out>/cls_sym_<병과>.png(256 정사각 · 투명) · --preview = 어두운 원 위 5종 확인 그림. 출력 = <out>/cls_sym_<병과>.png(256 정사각 · 투명) · --preview = 어두운 원 위 5종 확인 그림.
""" """
@ -22,7 +22,7 @@ def hexrgb(s):
return tuple(int(s[i:i + 2], 16) for i in (0, 2, 4)) return tuple(int(s[i:i + 2], 16) for i in (0, 2, 4))
def symbol(path, fill, line, size=256, pad=14, stroke=8, inner_lum=45, erode_passes=6, mono=True): def symbol(path, fill, line, size=256, pad=14, stroke=8, inner_lum=0, erode_passes=6, mono=True):
src = Image.open(path).convert("RGBA") src = Image.open(path).convert("RGBA")
bb = src.getchannel("A").point(lambda v: 255 if v > 40 else 0).getbbox() bb = src.getchannel("A").point(lambda v: 255 if v > 40 else 0).getbbox()
src = src.crop(bb) src = src.crop(bb)
@ -67,13 +67,14 @@ def main():
ap.add_argument("--line", default="#1A1A22") ap.add_argument("--line", default="#1A1A22")
ap.add_argument("--out", default="Assets/UI/Symbols") ap.add_argument("--out", default="Assets/UI/Symbols")
ap.add_argument("--preview", default="") ap.add_argument("--preview", default="")
ap.add_argument("--inner-lum", type=float, default=0.0, help="안쪽 선(원본의 진한 선) 밝기 기준 · 0 = 안쪽 선 없음(기본 · 입체감 없이 평면)")
ap.add_argument("--mono", action="store_true", help="단색(채움 한 색 · 안쪽 선 = 뚫린 선 · 테두리 없음) · 기본 = 검은 선 + 흰 채움") ap.add_argument("--mono", action="store_true", help="단색(채움 한 색 · 안쪽 선 = 뚫린 선 · 테두리 없음) · 기본 = 검은 선 + 흰 채움")
a = ap.parse_args() a = ap.parse_args()
out = os.path.join(ROOT, a.out) out = os.path.join(ROOT, a.out)
os.makedirs(out, exist_ok=True) os.makedirs(out, exist_ok=True)
tiles = [] tiles = []
for t in TYPES: for t in TYPES:
g = symbol(os.path.join(a.src, "cls_%s_%sA_rgba.png" % (t, a.seed)), hexrgb(a.fill), hexrgb(a.line), mono=a.mono) g = symbol(os.path.join(a.src, "cls_%s_%sA_rgba.png" % (t, a.seed)), hexrgb(a.fill), hexrgb(a.line), inner_lum=a.inner_lum, mono=a.mono)
g.save(os.path.join(out, "cls_sym_%s.png" % t)) g.save(os.path.join(out, "cls_sym_%s.png" % t))
tile = Image.new("RGBA", (300, 300), (0, 0, 0, 0)) tile = Image.new("RGBA", (300, 300), (0, 0, 0, 0))
tile.alpha_composite(g.resize((200, 200), Image.LANCZOS), (50, 50)) tile.alpha_composite(g.resize((200, 200), Image.LANCZOS), (50, 50))