로비 영웅 = 크기 표 기준으로 세움(관우만 작던 문제) · 축융 금빛 초커(턱선) · 하단 탭 글자 항상 + 선택 탭 다시 = 닫기 · 하단 탭 아이콘 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>
|
|
@ -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(짙은 피부 = 피부 판정 밖)
|
||||
|
|
|
|||
|
|
Before Width: | Height: | Size: 369 KiB After Width: | Height: | Size: 376 KiB |
|
Before Width: | Height: | Size: 360 KiB After Width: | Height: | Size: 368 KiB |
|
Before Width: | Height: | Size: 374 KiB After Width: | Height: | Size: 384 KiB |
|
|
@ -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,6 +178,8 @@ namespace TKS.OutGame
|
|||
{
|
||||
var h = S.Def(lineup[i].id);
|
||||
float x = (i - (n - 1) / 2f) * w;
|
||||
// 크기 표 기준으로 발 맞춰 세움(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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 > 1 = 위쪽 얼굴 부분 확대) · 없으면 병종 색 원 + 병종 글자.
|
||||
/// circle = 원형 틀(편성 자리) · false = 둥근 사각.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 72 KiB |
|
|
@ -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
|
||||
|
|
|
|||
|