로비 영웅 = 크기 표 기준으로 세움(관우만 작던 문제) · 축융 금빛 초커(턱선) · 하단 탭 글자 항상 + 선택 탭 다시 = 닫기 · 하단 탭 아이콘 5종 캐주얼 화풍(#1108 · PD 2026-11-10)

PD: 「로비에 배치된 관우의 크기만 작게 보이는 건지 체크해서 수정」 · 「축융의 얼굴 턱선이 없어서 얼굴이 너무 커보여」 · 「하단 아이콘이 선택되지 않았을 때에도 글자가 보이게 · 선택된 상태일 경우 X(닫기 버튼)처럼 동작」 · 「하단 아이콘을 우리 게임 화풍(캐주얼)에 맞게 다시 그려줘」
- 로비 원인: 출전 영웅을 칸(196×340)에 그림 틀째 맞춤 → 틀 = 세 자세 합집합이라 돌진 언월도로 넓은 관우(930 px)만 ×0.21(몸 153 px · 유비 185) → UiKit.UnitStand = 크기 표 size_px 기준 배율 + 기마 머리 끝 상한(BalanceConfig.mountedArtMaxTop) · 발 = 피벗 · LobbyUnitPx 206(유비 예전 크기)
- 축융: 맨 어깨라 얼굴·몸 피부가 이어져 턱이 없음 → 부분 다시 그리기 2 · 턱 호 덧칠 3 · 전체 재생성 1(피부가 하얘짐) 시험 → 채택 = 턱 아래 금빛 초커 덧칠(검정 외곽선 + 그림자 1단 · 생성 0 · 3자세) · 크기 표 눈 자동 측정 가능해짐 → adjust 1.18 → 1.02(카드 재현 확인)
- 하단 탭: 글자 = 모든 탭(선택 = 흰 34 · 아니면 흐린 30) · 아이콘 글자 위로 · OnTab 선택 탭 다시 = ShowLobby · VisibleTabLabels
- 아이콘: Assets/UI/Samguk/menu/tab_{hero,treasure,domestic,alliance,trade}.png = Krea 2 t2i 유닛과 같은 화풍 C · 20장 중 5 · 256² · 테마 치환(ui_delivered.csv md5)
- 테스트(고친 부분만): Lobby_Tabs_Back_ComingSoon(탭 글자 5 · 선택 탭 다시 = 로비 · 다시 열림) · UILayerTests · UnitArt_SizeTable 각 1/1 · error 0 · 캡처 lobby · hero_list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-10 13:50:57 +09:00
parent 8534ef88ab
commit f31ea226ab
14 changed files with 76 additions and 12 deletions

View File

@ -125,4 +125,4 @@ zhoucang,0,173.3,538.3,453,598.0,276.0,856,1091.8,,1.092,
zhoutai,0,162.2,609.1,429,599.5,273.0,885,993.6,,1.026,
zhugejin,0,160.2,562.8,372,501.0,270.0,870,954.7,,1.08,
zhugeliang,0,140.2,529.3,336,469.0,264.0,886,962.8,,1.18,
zhurong,0,118.3,458.4,0,0,0,773,821.6,,1.18,눈 수동 실측 2026-11-10(눈 간격·눈 높이): 눈 덩어리 중심 x 524.4 · 642.7(짙은 피부 = 피부 판정 밖)
zhurong,0,118.6,458.1,261,524.0,258.0,773,758.1,,1.02,눈 수동 실측 2026-11-10(눈 간격·눈 높이): 눈 덩어리 중심 x 524.4 · 642.7(짙은 피부 = 피부 판정 밖)

1 art mounted eye_px eye_up_px face_px head_px crown_px body_px size_px lock adjust note
125 zhoutai 0 162.2 609.1 429 599.5 273.0 885 993.6 1.026
126 zhugejin 0 160.2 562.8 372 501.0 270.0 870 954.7 1.08
127 zhugeliang 0 140.2 529.3 336 469.0 264.0 886 962.8 1.18
128 zhurong 0 118.3 118.6 458.4 458.1 0 261 0 524.0 0 258.0 773 821.6 758.1 1.18 1.02 눈 수동 실측 2026-11-10(눈 간격·눈 높이): 눈 덩어리 중심 x 524.4 · 642.7(짙은 피부 = 피부 판정 밖)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 KiB

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 384 KiB

View File

@ -16,6 +16,8 @@ namespace TKS.OutGame
Text sortieSub;
Text chestBadge;
RectTransform field;
/// <summary>로비 출전 영웅 표준 키(px · 크기 표 size_px 가 이 높이) — 유비가 예전 칸 맞춤 때와 같은 크기(797×826 틀 → 196 칸 = ×0.246 · size 837 × 0.246 ≈ 206).</summary>
const float LobbyUnitPx = 206f;
static RectTransform At(Transform p, string name, float x, float y, float w, float h)
{
@ -176,7 +178,9 @@ namespace TKS.OutGame
{
var h = S.Def(lineup[i].id);
float x = (i - (n - 1) / 2f) * w;
UiKit.Portrait("Hero" + i, field, h, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(x, 20f), new Vector2(w, 340f), false, 1f, Color.clear);
// 크기 표 기준으로 발 맞춰 세움(PD 2026-11-10 「로비 관우만 작게 보임」 = 칸에 그림 틀을 맞추면 틀이 넓은 관우만 작아짐) · 일러 없으면 초상
if (UiKit.UnitStand("Hero" + i, field, h, new Vector2(0.5f, 0f), new Vector2(x, 20f), LobbyUnitPx, cfg.mountedArtMaxTop) == null)
UiKit.Portrait("Hero" + i, field, h, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(x, 20f), new Vector2(w, 340f), false, 1f, Color.clear);
}
}
}

View File

@ -273,12 +273,17 @@ namespace TKS.OutGame
if (UISkin.On)
{
tabImages[i].gameObject.SetActive(on);
tabTexts[i].gameObject.SetActive(on);
// 글자 = 선택 안 된 탭도 항상(PD 2026-11-10 「선택되지 않았을 때에도 글자가 보이게」) · 선택 = 흰 큰 글자 · 아니면 흐린 작은 글자(동맹 = 잠김 색 그대로)
var t = tabTexts[i];
t.gameObject.SetActive(true);
t.color = on ? UiKit.White : tabOffText;
t.fontSize = on ? TabLabelOn : TabLabelOff;
t.rectTransform.anchoredPosition = new Vector2(0f, on ? TabLabelYOn : TabLabelYOff);
var ic = i < tabIcons.Count ? tabIcons[i] : null;
if (ic != null)
{
ic.sizeDelta = Vector2.one * (on ? 118f : 104f);
ic.anchoredPosition = new Vector2(0f, on ? 48f : 30f);
ic.sizeDelta = Vector2.one * (on ? TabIconOn : TabIconOff);
ic.anchoredPosition = new Vector2(0f, on ? TabIconYOn : TabIconYOff);
}
}
else tabImages[i].color = on ? UiKit.Red : UiKit.Dark;
@ -438,6 +443,24 @@ namespace TKS.OutGame
// ---------- 하단 탭 ----------
// 탭 배치(px · 탭 바 아래 기준) — 글자를 항상 보이게 바꾸며(PD 2026-11-10) 아이콘을 글자 위로 올림 · 선택 탭 = 솟음 판(168) 위로 크게
const float TabIconOff = 96f, TabIconOn = 118f, TabIconYOff = 46f, TabIconYOn = 52f;
const int TabLabelOff = 30, TabLabelOn = 34;
const float TabLabelYOff = 24f, TabLabelYOn = 30f;
Color tabOffText = Color.gray;
/// <summary>글자가 켜진 하단 탭 수(테스트 · PD 2026-11-10 「선택되지 않은 탭도 글자」).</summary>
public int VisibleTabLabels
{
get
{
int n = 0;
foreach (var t in tabTexts)
if (t != null && t.gameObject.activeSelf) n++;
return n;
}
}
void BuildTabBar()
{
var bar = UiKit.Rect("TabBar", mainCanvas.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), Vector2.zero, new Vector2(Reference.x, TabBarH));
@ -451,6 +474,7 @@ namespace TKS.OutGame
string[] marks = { "영", "보", "내", "잠", "거" };
string[] icons = { "tab_hero", "tab_treasure", "tab_domestic", "tab_alliance", "tab_trade" };
Color off = UISkin.Col("bar_text_off", new Color(0.62f, 0.58f, 0.55f));
tabOffText = off;
for (int i = 0; i < names.Length; i++)
{
int k = i;
@ -470,7 +494,7 @@ namespace TKS.OutGame
img = UiKit.Skin(focus, "tab_focus", UiKit.Col("tab_focus", UiKit.Red));
if (UISkin.Has("tab_focus_light"))
UiKit.Skin(UiKit.Rect("Light", focus, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -6f), new Vector2(188f, 70f)), "tab_focus_light", UiKit.Col("tab_focus_light", UiKit.White));
var ic = UiKit.Icon(cell, icons[i], new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 30f), 104f);
var ic = UiKit.Icon(cell, icons[i], new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, TabIconYOff), TabIconOff);
if (ic != null)
{
if (i == 3) ic.color = UiKit.Col("tab_locked", off);
@ -489,7 +513,7 @@ namespace TKS.OutGame
UiKit.FillLabel(dot.transform, marks[i], 32, i == 3 ? new Color(0.7f, 0.66f, 0.62f) : UiKit.White);
}
var t = UISkin.On
? UiKit.Label(cell, names[i], 36, UiKit.White, TextAnchor.MiddleCenter, new Vector2(0.5f, 0f), new Vector2(0.5f, 0.5f), new Vector2(0f, 36f), new Vector2(204f, 50f))
? UiKit.Label(cell, names[i], TabLabelOff, off, TextAnchor.MiddleCenter, new Vector2(0.5f, 0f), new Vector2(0.5f, 0.5f), new Vector2(0f, TabLabelYOff), new Vector2(204f, 50f))
: UiKit.Label(cell, names[i], 32, i == 3 ? off : UiKit.White, TextAnchor.MiddleCenter, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 14f), new Vector2(200f, 48f));
if (UISkin.On) UiKit.Title(t, true);
tabImages.Add(img);
@ -499,6 +523,12 @@ namespace TKS.OutGame
public void OnTab(int i)
{
// 선택된 탭을 다시 누르면 닫기 = 로비(PD 2026-11-10 「해당 메뉴가 선택된 상태일 경우 X(닫기 버튼)처럼 동작」)
if (current != null && current != Lobby && current.Tab == i)
{
ShowLobby();
return;
}
switch (i)
{
case 0: Show(HeroList); break;

View File

@ -768,6 +768,28 @@ namespace TKS.OutGame
return sp;
}
/// <summary>
/// 서 있는 유닛(발 = anchor + pos) — 크기 표 size_px 기준 배율(standardPx ÷ size_px = 머리 크기 통일 · 영웅 목록·전투와 같은 기준) ·
/// 기마 = 머리 끝이 standardPx × mountedMaxTop 을 넘지 않게(전투 FrameAnimator 와 같은 상한) · 일러·피벗이 없으면 null(호출 쪽이 초상으로 대체).
/// PD 2026-11-10 「로비에 배치된 관우의 크기만 작게 보임」 — 칸에 그림 틀을 맞추면 틀이 넓은 유닛(관우 언월도)만 작아짐.
/// </summary>
public static RectTransform UnitStand(string name, Transform parent, HeroDb.Hero h, Vector2 anchor, Vector2 pos, float standardPx, float mountedMaxTop)
{
var sp = h != null ? ArtSprite(h.art) : null;
var a = h != null ? UnitArt.Load(h.art) : null;
if (sp == null || a == null || a.Meta.pivot == null || a.Meta.pivot.Length < 2) return null;
float size = a.SizePx > 0.5f ? a.SizePx : a.BodyPx;
if (size <= 0.5f) return null;
float k = standardPx / size;
float top = a.BodyPx * k;
if (a.Mounted && mountedMaxTop > 0.01f && top > standardPx * mountedMaxTop) k *= standardPx * mountedMaxTop / top;
var rt = Rect(name, parent, anchor, new Vector2(0.5f, a.Meta.pivot[1]), pos, sp.rect.size * k);
var img = rt.gameObject.AddComponent<Image>();
img.sprite = sp;
img.raycastTarget = false;
return rt;
}
/// <summary>
/// 초상(틀 안을 마스크) — 일러가 있으면 그 그림(zoom &gt; 1 = 위쪽 얼굴 부분 확대) · 없으면 병종 색 원 + 병종 글자.
/// circle = 원형 틀(편성 자리) · false = 둥근 사각.

View File

@ -478,6 +478,14 @@ namespace TKS.Tests
og.OnTab(0);
Assert.AreEqual(og.HeroList, og.Current);
yield return null;
// PD 2026-11-10: 하단 탭 글자 = 선택 안 된 탭도 · 선택된 탭 다시 누르면 닫기(로비)
Assert.AreEqual(5, og.VisibleTabLabels, "하단 탭 글자 5개 모두 보임");
og.OnTab(0);
Assert.AreEqual(og.Lobby, og.Current, "선택된 탭 다시 = 닫기(로비)");
Assert.AreEqual(5, og.VisibleTabLabels, "로비에서도 탭 글자 보임");
og.OnTab(0);
Assert.AreEqual(og.HeroList, og.Current, "다시 열림");
yield return null;
Assert.AreEqual(og.Session.Owned(false).Count, og.HeroList.CardCount, "보유 장수 카드");
// 미보유 장수 = 빈 카드가 아니라 그 영웅 그림 카드(PD 2026-11-10 「유닛 목록에 장수들의 모습이 보이도록」)
int heroTotal = 0;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -70,11 +70,11 @@ skill_spear_a,logo_skill,Assets/UI/Samguk/logo_skill/skill_spear_a.png,1ee53fa18
skill_spear_p,logo_skill,Assets/UI/Samguk/logo_skill/skill_spear_p.png,1ea22555662c8c19934064e0d54a4076,ui_logo_skill
skill_strategist_a,logo_skill,Assets/UI/Samguk/logo_skill/skill_strategist_a.png,1caceeaaa3e566e50ef9e80bdd3d30f7,ui_logo_skill
skill_strategist_p,logo_skill,Assets/UI/Samguk/logo_skill/skill_strategist_p.png,67a37d7ef0e37f64169a7c3014aa937a,ui_logo_skill
tab_alliance,menu,Assets/UI/Samguk/menu/tab_alliance.png,b43aa0b723ce2953c5b1b179feae9969,ui_menu
tab_domestic,menu,Assets/UI/Samguk/menu/tab_domestic.png,3f9a7e8b0110ff3543b5d346618d639d,ui_menu
tab_hero,menu,Assets/UI/Samguk/menu/tab_hero.png,b552c5a1d72dc1e50381b665500dd41e,ui_menu
tab_trade,menu,Assets/UI/Samguk/menu/tab_trade.png,46c477c1f8defb62b16630045891ae99,ui_menu
tab_treasure,menu,Assets/UI/Samguk/menu/tab_treasure.png,a5b6125f6b46748a69b677a50bb01dc7,ui_menu
tab_alliance,menu,Assets/UI/Samguk/menu/tab_alliance.png,baef297a314e2848f0104a8930ac8426,ui_tab_casual_20261110
tab_domestic,menu,Assets/UI/Samguk/menu/tab_domestic.png,e7df3d5127965baf0904d86356780b19,ui_tab_casual_20261110
tab_hero,menu,Assets/UI/Samguk/menu/tab_hero.png,6e9a32f84d1e2221755e792decd002c7,ui_tab_casual_20261110
tab_trade,menu,Assets/UI/Samguk/menu/tab_trade.png,aebe733f146eb20a22fd25ccfd4d0c81,ui_tab_casual_20261110
tab_treasure,menu,Assets/UI/Samguk/menu/tab_treasure.png,f7dc5942a8caf78310541826105b477f,ui_tab_casual_20261110
tile_bridge,gimmick,Assets/UI/Samguk/gimmick/tile_bridge.png,80728d733f5477174a209c42feab1aba,ui_gimmick
tile_burning,gimmick,Assets/UI/Samguk/gimmick/tile_burning.png,a49ab2ede2802a68b40f3410817f9bc6,ui_gimmick
tile_fog,gimmick,Assets/UI/Samguk/gimmick/tile_fog.png,7b9ab096a721c3efcc229dabb53efb41,ui_gimmick

1 id group path md5 batch
70 skill_spear_p logo_skill Assets/UI/Samguk/logo_skill/skill_spear_p.png 1ea22555662c8c19934064e0d54a4076 ui_logo_skill
71 skill_strategist_a logo_skill Assets/UI/Samguk/logo_skill/skill_strategist_a.png 1caceeaaa3e566e50ef9e80bdd3d30f7 ui_logo_skill
72 skill_strategist_p logo_skill Assets/UI/Samguk/logo_skill/skill_strategist_p.png 67a37d7ef0e37f64169a7c3014aa937a ui_logo_skill
73 tab_alliance menu Assets/UI/Samguk/menu/tab_alliance.png b43aa0b723ce2953c5b1b179feae9969 baef297a314e2848f0104a8930ac8426 ui_menu ui_tab_casual_20261110
74 tab_domestic menu Assets/UI/Samguk/menu/tab_domestic.png 3f9a7e8b0110ff3543b5d346618d639d e7df3d5127965baf0904d86356780b19 ui_menu ui_tab_casual_20261110
75 tab_hero menu Assets/UI/Samguk/menu/tab_hero.png b552c5a1d72dc1e50381b665500dd41e 6e9a32f84d1e2221755e792decd002c7 ui_menu ui_tab_casual_20261110
76 tab_trade menu Assets/UI/Samguk/menu/tab_trade.png 46c477c1f8defb62b16630045891ae99 aebe733f146eb20a22fd25ccfd4d0c81 ui_menu ui_tab_casual_20261110
77 tab_treasure menu Assets/UI/Samguk/menu/tab_treasure.png a5b6125f6b46748a69b677a50bb01dc7 f7dc5942a8caf78310541826105b477f ui_menu ui_tab_casual_20261110
78 tile_bridge gimmick Assets/UI/Samguk/gimmick/tile_bridge.png 80728d733f5477174a209c42feab1aba ui_gimmick
79 tile_burning gimmick Assets/UI/Samguk/gimmick/tile_burning.png a49ab2ede2802a68b40f3410817f9bc6 ui_gimmick
80 tile_fog gimmick Assets/UI/Samguk/gimmick/tile_fog.png 7b9ab096a721c3efcc229dabb53efb41 ui_gimmick