Fable 검수(나머지1) 결함 1~10 반영 — 결과 · 공용 팝업 · 거래(#1104)

- 결과: 결과 단계 HUD 전체 숨김(BattleHUD.HideOnResult · 제목 2중 제거) · 「다시」 = 군량 비용 칩(부족 = 회색) · 「첫 클리어」 글자 → 타일 「첫」 뱃지 · 레벨업 = 노란 글자 칩 + 위 화살표 · 패널 = 섹션 패널 층(프레임 #3F4262 + 필드 + 광택) · 높이 1180 → 1080
- 팝업: 제목 띠 색 통일(popup_band #1F2138) · 스테이지 팝업 띠 h110 + 왼쪽 스테이지 칩 · 본문 필드 위 126 · 출정 버튼 바닥 여백 52 · 군량 팝업 디버그 문구 삭제 · 「보기」 = btn_green(비율 통일)
- 행 판 통일: row_on_field = 흰 8 %(결과 · 팝업 · 거래 · 내정 전부 밝은 행)
- 거래: 「픽업」 = 배너 안 뱃지 하나(칩 = 「기간 2주」) · 배너 600 · 천장 176 · 확률 행 80 · 버튼 행 탭 바 위 24 고정 · 픽업 그림 = 아트 있는 영웅만 크게 + 이름 칩(「기」 자리 원 제거)
- 테스트 117/117 · console error 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-09 18:19:06 +09:00
parent 4f22c4e091
commit 896c5237c6
8 changed files with 108 additions and 43 deletions

View File

@ -430,7 +430,7 @@ color,row_label_strip,,,,,,#FFFFFF0A,편성 라벨 칸 세로 띠(흰 4 %)
font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전) font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
color,text_on_yellow,,,,,,#1E1E2A,노랑 Primary 위 글자(Fable §5-8) color,text_on_yellow,,,,,,#1E1E2A,노랑 Primary 위 글자(Fable §5-8)
color,ribbon_glow,,,,,,#FFD24AFF,결과 리본 뒤 금빛(그림 자체가 가운데 α 0.5 라 틴트 α 1 · Fable §4-2 α 0.35 는 안 보임 실측) color,ribbon_glow,,,,,,#FFD24AFF,결과 리본 뒤 금빛(그림 자체가 가운데 α 0.5 라 틴트 α 1 · Fable §4-2 α 0.35 는 안 보임 실측)
color,row_on_field,,,,,,#3F4262,필드 위 행 판(필드보다 밝게 · 팝업 교환 행) color,row_on_field,,,,,,#FFFFFF14,필드 위 행 판(흰 8 % · 전 화면 밝은 행 통일 · Fable 검수 나머지1 결함 6)
skin,btn_l_yellow,Button/Button01_l_Yellow.png,,1.3,,,,Primary 노랑 h110(확인·10연·열기 · Fable §5-5) skin,btn_l_yellow,Button/Button01_l_Yellow.png,,1.3,,,,Primary 노랑 h110(확인·10연·열기 · Fable §5-5)
skin,btn_l_red,Button/Button01_l_White_Bg.png,Button/Button01_l_White_Light1.png,1.35,5;5;5;18,0.35,,Primary 붉은 h104(출정 · 틴트 red) skin,btn_l_red,Button/Button01_l_White_Bg.png,Button/Button01_l_White_Light1.png,1.35,5;5;5;18,0.35,,Primary 붉은 h104(출정 · 틴트 red)
skin,title_divider_l,Label/Title_Line01_Divider_Left.png,,1,,,,소제목 왼쪽 선(Fable §5-2) skin,title_divider_l,Label/Title_Line01_Divider_Left.png,,1,,,,소제목 왼쪽 선(Fable §5-2)
@ -493,3 +493,5 @@ icon,hud_ally,Icon_PictoIcons/128/PictoIcon_Helmet_1.Png,,,,,,전투 HUD 아군
icon,hud_enemy,Icon_PictoIcons/128/PictoIcon_Boss.Png,,,,,,전투 HUD 적 수 아이콘 icon,hud_enemy,Icon_PictoIcons/128/PictoIcon_Boss.Png,,,,,,전투 HUD 적 수 아이콘
color,skill_glow,,,,,,#FFD24AFF,스킬 버튼 뒤 빛(사용 가능 · 금빛 · 붉은 버튼·모래 바탕과 대비) color,skill_glow,,,,,,#FFD24AFF,스킬 버튼 뒤 빛(사용 가능 · 금빛 · 붉은 버튼·모래 바탕과 대비)
icon,shield,IconMisc/Icon_Shield.png,,,,,,방어 스탯(Fable §5-8) icon,shield,IconMisc/Icon_Shield.png,,,,,,방어 스탯(Fable §5-8)
color,popup_band,,,,,,#1F2138,팝업 제목 띠(공용 · 스테이지 팝업 통일 · 검수 결함 6)
skin,btn_green,Button/Button01_s_Green.png,,1.22,,,,Secondary 녹 h100(광고 보기 · btn_sky 와 같은 비율)

1 kind id path overlay ppu inset alpha color note
430 font title Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf 제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
431 color text_on_yellow #1E1E2A 노랑 Primary 위 글자(Fable §5-8)
432 color ribbon_glow #FFD24AFF 결과 리본 뒤 금빛(그림 자체가 가운데 α 0.5 라 틴트 α 1 · Fable §4-2 α 0.35 는 안 보임 실측)
433 color row_on_field #3F4262 #FFFFFF14 필드 위 행 판(필드보다 밝게 · 팝업 교환 행) 필드 위 행 판(흰 8 % · 전 화면 밝은 행 통일 · Fable 검수 나머지1 결함 6)
434 skin btn_l_yellow Button/Button01_l_Yellow.png 1.3 Primary 노랑 h110(확인·10연·열기 · Fable §5-5)
435 skin btn_l_red Button/Button01_l_White_Bg.png Button/Button01_l_White_Light1.png 1.35 5;5;5;18 0.35 Primary 붉은 h104(출정 · 틴트 red)
436 skin title_divider_l Label/Title_Line01_Divider_Left.png 1 소제목 왼쪽 선(Fable §5-2)
493 icon hud_enemy Icon_PictoIcons/128/PictoIcon_Boss.Png 전투 HUD 적 수 아이콘
494 color skill_glow #FFD24AFF 스킬 버튼 뒤 빛(사용 가능 · 금빛 · 붉은 버튼·모래 바탕과 대비)
495 icon shield IconMisc/Icon_Shield.png 방어 스탯(Fable §5-8)
496 color popup_band #1F2138 팝업 제목 띠(공용 · 스테이지 팝업 통일 · 검수 결함 6)
497 skin btn_green Button/Button01_s_Green.png 1.22 Secondary 녹 h100(광고 보기 · btn_sky 와 같은 비율)

View File

@ -504,7 +504,7 @@ MonoBehaviour:
- id: ribbon_glow - id: ribbon_glow
color: {r: 1, g: 0.8235294, b: 0.2901961, a: 1} color: {r: 1, g: 0.8235294, b: 0.2901961, a: 1}
- id: row_on_field - id: row_on_field
color: {r: 0.24705882, g: 0.25882354, b: 0.38431373, a: 1} color: {r: 1, g: 1, b: 1, a: 0.078431375}
- id: banner_pattern - id: banner_pattern
color: {r: 1, g: 1, b: 1, a: 0.078431375} color: {r: 1, g: 1, b: 1, a: 0.078431375}
- id: chest_bronze - id: chest_bronze
@ -569,6 +569,8 @@ MonoBehaviour:
color: {r: 1, g: 1, b: 1, a: 0.2509804} color: {r: 1, g: 1, b: 1, a: 0.2509804}
- id: skill_glow - id: skill_glow
color: {r: 1, g: 0.8235294, b: 0.2901961, a: 1} color: {r: 1, g: 0.8235294, b: 0.2901961, a: 1}
- id: popup_band
color: {r: 0.12156863, g: 0.12941177, b: 0.21960784, a: 1}
skins: skins:
- id: card - id: card
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3} pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
@ -1340,6 +1342,13 @@ MonoBehaviour:
ppu: 1.5 ppu: 1.5
inset: {x: 0, y: 0, z: 0, w: 0} inset: {x: 0, y: 0, z: 0, w: 0}
overlayAlpha: 1 overlayAlpha: 1
- id: btn_green
pack: {fileID: 21300000, guid: 2d734a17e89824d30b1f014a9c1f5f60, type: 3}
samguk: {fileID: 0}
overlay: {fileID: 0}
ppu: 1.22
inset: {x: 0, y: 0, z: 0, w: 0}
overlayAlpha: 1
icons: icons:
- id: cur_gold - id: cur_gold
pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3} pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3}

View File

@ -14,7 +14,7 @@ namespace TKS.OutGame
{ {
// 패널 배치(UI px · 패널 왼쪽 위 기준) // 패널 배치(UI px · 패널 왼쪽 위 기준)
const float PW = 920f; const float PW = 920f;
const float PH = 1180f; const float PH = 1080f;
const float Side = 60f; const float Side = 60f;
const float RowW = PW - Side * 2f; const float RowW = PW - Side * 2f;
const float RowH = 64f; const float RowH = 64f;
@ -32,6 +32,7 @@ namespace TKS.OutGame
readonly Text plain; readonly Text plain;
readonly Button retry; readonly Button retry;
readonly Button ok; readonly Button ok;
readonly Text retryCost;
string rewardsText = ""; string rewardsText = "";
public bool Visible public bool Visible
@ -50,8 +51,8 @@ namespace TKS.OutGame
var dim = UiKit.Fill("Result", canvas); var dim = UiKit.Fill("Result", canvas);
UiKit.Paint(dim, UISkin.Col("dim", new Color(0f, 0f, 0f, 0.55f)), false); UiKit.Paint(dim, UISkin.Col("dim", new Color(0f, 0f, 0f, 0.55f)), false);
go = dim.gameObject; go = dim.gameObject;
Image panel; Image panel = null;
if (UISkin.Has("popup")) if (UISkin.Has("popup") && UISkin.Has("panel_frame"))
{ {
// 리본 뒤 금빛(승리만 · 팩 Glow_Circle01 · 호흡) → 팩 팝업 틀 → 제목 리본(승리 붉은 · 패배 회색) // 리본 뒤 금빛(승리만 · 팩 Glow_Circle01 · 호흡) → 팩 팝업 틀 → 제목 리본(승리 붉은 · 패배 회색)
if (UISkin.Has("glow_circle")) if (UISkin.Has("glow_circle"))
@ -61,13 +62,17 @@ namespace TKS.OutGame
pulse.min = 0.65f; pulse.min = 0.65f;
pulse.period = 1.6f; pulse.period = 1.6f;
} }
panel = UiKit.Skin(UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(PW, PH)), "popup", UiKit.Paper); // 패널 = 섹션 패널 층(그림자 · 밝은 프레임 #3F4262 · 필드 #262840 · 윗면 광택 · 검수 결함 10)
var rib = UiKit.Rect("Ribbon", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), new Vector2(1000f, 200f)); var holder = UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(PW, PH));
RectTransform froot;
UiKit.SectionPanel(holder, "Frame", 0f, 0f, PW, PH, false, false, out froot);
var pt = (Transform)holder;
var rib = UiKit.Rect("Ribbon", pt, new Vector2(0.5f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), new Vector2(1000f, 200f));
ribbon = UiKit.Skin(rib, "ribbon", Color.white); ribbon = UiKit.Skin(rib, "ribbon", Color.white);
title = UiKit.Title(UiKit.FillLabel(rib, "", 88, UiKit.White, TextAnchor.MiddleCenter, true, 150f), true); title = UiKit.Title(UiKit.FillLabel(rib, "", 88, UiKit.White, TextAnchor.MiddleCenter, true, 150f), true);
title.rectTransform.offsetMin = new Vector2(150f, 34f); title.rectTransform.offsetMin = new Vector2(150f, 34f);
// 별 3 = 받침 원(Circle78 chip_dark) + 별(가운데 크게 · 위로) · 0.15 s 간격 튀김 // 별 3 = 받침 원(Circle78 chip_dark) + 별(가운데 크게 · 위로) · 0.15 s 간격 튀김
starRow = UiKit.At(panel.transform, "StarRow", 0f, 120f, PW, 190f); starRow = UiKit.At(pt, "StarRow", 0f, 120f, PW, 190f);
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
bool mid = i == 1; bool mid = i == 1;
@ -79,9 +84,10 @@ namespace TKS.OutGame
UiKit.DropShadow(starImg[i], 5f); UiKit.DropShadow(starImg[i], 5f);
starImg[i].gameObject.AddComponent<UiPop>().delay = 0.15f * i; starImg[i].gameObject.AddComponent<UiPop>().delay = 0.15f * i;
} }
body = UiKit.Fill("Body", panel.transform); body = UiKit.Fill("Body", pt);
retry = UiKit.SkinBtn(panel.transform, "Retry", "round08", UiKit.Col("menu_btn", UiKit.Dark), "다시", 40, UiKit.White, Side, BtnY, 260f, 110f, () => root.RetryStage()); retry = UiKit.SkinBtn(pt, "Retry", "round08", UiKit.Col("menu_btn", UiKit.Dark), "다시", 34, UiKit.White, Side, BtnY, 260f, 110f, () => root.RetryStage());
ok = UiKit.SkinBtn(panel.transform, "Ok", UISkin.Has("btn_l_yellow") ? "btn_l_yellow" : "button", UISkin.Has("btn_l_yellow") ? UiKit.White : UiKit.Coin, "확인", 46, UiKit.Col("text_on_yellow", UiKit.Ink), PW - Side - 520f, BtnY, 520f, 110f, null); retryCost = UiKit.BtnCost(retry, "cur_stamina", "", 36f, 28); // 재도전 = 군량 소모 표시(검수 결함 2)
ok = UiKit.SkinBtn(pt, "Ok", UISkin.Has("btn_l_yellow") ? "btn_l_yellow" : "button", UISkin.Has("btn_l_yellow") ? UiKit.White : UiKit.Coin, "확인", 46, UiKit.Col("text_on_yellow", UiKit.Ink), PW - Side - 520f, BtnY, 520f, 110f, null);
} }
else else
{ {
@ -117,6 +123,12 @@ namespace TKS.OutGame
title.text = (r.win ? "승리" : "패배") + " <size=44>" + r.chapter + "-" + r.stage + (r.boss ? " 보스" : "") + "</size>"; title.text = (r.win ? "승리" : "패배") + " <size=44>" + r.chapter + "-" + r.stage + (r.boss ? " 보스" : "") + "</size>";
ShowStars(r.win ? r.stars : 0, r.win); ShowStars(r.win ? r.stars : 0, r.win);
SetButtons(true); SetButtons(true);
if (retryCost != null && root.Battle != null && root.Battle.Config != null && root.Battle.StageIndex >= 0 && root.Battle.StageIndex < root.Battle.Config.stages.Length)
{
int cost = EconomyRules.StageCost(s.Db, s.Save, root.Battle.Config.stages[root.Battle.StageIndex]);
retryCost.text = cost.ToString();
retry.GetComponent<Image>().color = s.Save.stamina >= cost ? UiKit.Col("menu_btn", UiKit.Dark) : UiKit.Col("disabled", UiKit.Disabled);
}
if (body == null) if (body == null)
{ {
plain.text = (r.win ? "별 " + UiKit.Stars(r.stars, 3) + "\n\n" : "아군이 전멸했습니다\n\n") + rewardsText; plain.text = (r.win ? "별 " + UiKit.Stars(r.stars, 3) + "\n\n" : "아군이 전멸했습니다\n\n") + rewardsText;
@ -146,14 +158,14 @@ namespace TKS.OutGame
return; return;
} }
Tiles(s, r, y); Tiles(s, r, y);
Notes(s, r, y + Tile + 60f); Notes(s, r, y + Tile + 62f);
} }
/// <summary>보상 타일 행(가운데 정렬 · 칸 아래 이름) — 골드 · 경험 · 보옥(있을 때) · 장비(등급 칸 · 있을 때) · 상자(있을 때).</summary> /// <summary>보상 타일 행(가운데 정렬 · 칸 아래 이름) — 골드 · 경험 · 보옥(있을 때) · 장비(등급 칸 · 있을 때) · 상자(있을 때).</summary>
void Tiles(OutGameSession s, StageReward r, float y) void Tiles(OutGameSession s, StageReward r, float y)
{ {
var list = new List<string[]>(); // 아이콘 · 수량 · 칸 색 접두 · 이름 var list = new List<string[]>(); // 아이콘 · 수량 · 칸 색 접두 · 이름
list.Add(new[] { "cur_gold", r.gold.ToString("N0"), "gear_white_", "골드" }); list.Add(new[] { "cur_gold", r.gold.ToString("N0"), "gear_white_", r.first ? "골드" : "골드 ×" + s.Db.Economy.RepeatRewardMult });
list.Add(new[] { "cur_exp", r.exp.ToString("N0"), "gear_white_", "경험 · " + r.expTo.Count + "명" }); list.Add(new[] { "cur_exp", r.exp.ToString("N0"), "gear_white_", "경험 · " + r.expTo.Count + "명" });
if (r.gem > 0) list.Add(new[] { "cur_gem", r.gem.ToString("N0"), "gear_blue_", "보옥" }); if (r.gem > 0) list.Add(new[] { "cur_gem", r.gem.ToString("N0"), "gear_blue_", "보옥" });
if (!string.IsNullOrEmpty(r.gearId)) if (!string.IsNullOrEmpty(r.gearId))
@ -170,22 +182,33 @@ namespace TKS.OutGame
{ {
var e = list[i]; var e = list[i];
float tx = x + i * (Tile + gap); float tx = x + i * (Tile + gap);
UiKit.RewardTile(body, "Tile" + i, tx, y, Tile, e[2], e[0], e[1], e[2] != "gear_white_"); var cell = UiKit.RewardTile(body, "Tile" + i, tx, y, Tile, e[2], e[0], e[1], e[2] != "gear_white_");
if (r.first && (e[0] == "cur_gold" || e[0] == "cur_gem")) FirstBadge(cell); // 첫 클리어 = 뱃지(스테이지 팝업과 같은 표현 · 검수 결함 8)
var n = UiKit.Label(body, e[3], 26, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.UpperCenter, new Vector2(0f, 1f), new Vector2(0.5f, 1f), new Vector2(tx + Tile * 0.5f, -y - Tile - 12f), new Vector2(Tile + gap, 36f), false); var n = UiKit.Label(body, e[3], 26, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.UpperCenter, new Vector2(0f, 1f), new Vector2(0.5f, 1f), new Vector2(tx + Tile * 0.5f, -y - Tile - 12f), new Vector2(Tile + gap, 36f), false);
n.horizontalOverflow = HorizontalWrapMode.Overflow; n.horizontalOverflow = HorizontalWrapMode.Overflow;
} }
} }
/// <summary>타일 아래 한두 줄 — 첫 클리어/반복 배율 · 레벨업 가능 영웅 · 소탕.</summary> /// <summary>「첫」 뱃지(Label_Badge01_Yellow · 칸 오른쪽 위).</summary>
public static void FirstBadge(Transform cell)
{
var b = UiKit.Icon(cell, "badge_first", new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-8f, -6f), 58f);
if (b != null) UiKit.Title(UiKit.FillLabel(b.transform, "첫", 24, UiKit.White), true);
}
/// <summary>타일 아래 = 레벨업 가능 칩(위 화살표 + 노란 글자 · 검수 결함 8) · 없으면 비움.</summary>
void Notes(OutGameSession s, StageReward r, float y) void Notes(OutGameSession s, StageReward r, float y)
{ {
var e = s.Db.Economy;
var sb = new StringBuilder(r.first ? "첫 클리어 보상" + (r.boss ? " + 보스" : "") : "반복 보상 ×" + e.RepeatRewardMult);
if (r.sweep) sb.Append(" · 소탕(군량 ").Append(r.stamina).Append(")");
var ready = ReadyNames(s, r); var ready = ReadyNames(s, r);
if (ready.Length > 0) sb.Append("\n<color=#").Append(ColorUtility.ToHtmlStringRGB(UiKit.Col("alert_red", UiKit.Red))).Append(">레벨업 가능 ").Append(ready).Append("</color>"); if (ready.Length == 0) return;
var t = UiKit.Label(body, sb.ToString(), 30, UiKit.White, TextAnchor.UpperCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Side, -y), new Vector2(RowW, 100f), false); string text = "레벨업 가능 " + ready;
t.lineSpacing = 1.2f; var t = UiKit.InfoChip(body, "LevelUp", Side, y, RowW, 56f, "up_green", text, 28);
t.color = UiKit.Col("select_line", UiKit.Coin);
float w = Mathf.Min(RowW, Mathf.Ceil(t.preferredWidth) + 110f);
var c = (RectTransform)t.transform.parent;
c.anchoredPosition = new Vector2((PW - w) * 0.5f, -y);
c.sizeDelta = new Vector2(w, 56f);
t.rectTransform.sizeDelta = new Vector2(w - 80f, 56f);
} }
/// <summary>연무장 결과(탑 · 던전 · 투기장 · 적장 토벌 · PD #1093 C) — 별 없음 · 결과 행 · 탭 = 연무장.</summary> /// <summary>연무장 결과(탑 · 던전 · 투기장 · 적장 토벌 · PD #1093 C) — 별 없음 · 결과 행 · 탭 = 연무장.</summary>

View File

@ -173,6 +173,7 @@ namespace TKS.OutGame
{ {
Battle = b; Battle = b;
hud = h; hud = h;
if (h != null) h.HideOnResult = true;
sling = s; sling = s;
Map = wm; Map = wm;
Cam = cam; Cam = cam;
@ -557,7 +558,7 @@ namespace TKS.OutGame
// 팩 팝업: 흰 틀 + 위 제목 띠(진남 틴트 · 광택) + 닫기 X // 팩 팝업: 흰 틀 + 위 제목 띠(진남 틴트 · 광택) + 닫기 X
panel = UiKit.Skin(UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(940f, h)), "popup", UiKit.Paper, true); panel = UiKit.Skin(UiKit.Rect("Panel", dim, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 20f), new Vector2(940f, h)), "popup", UiKit.Paper, true);
head = UiKit.TopBand("Head", panel.transform, 6f, 110f, 7f, 7f); head = UiKit.TopBand("Head", panel.transform, 6f, 110f, 7f, 7f);
UiKit.Skin(head, "popup_head", UiKit.Header); UiKit.Skin(head, "popup_head", UiKit.Col("popup_band", UiKit.Header)); // 팝업 제목 띠 통일(검수 결함 6)
var tt = UiKit.Title(UiKit.FillLabel(head, title, 44, UiKit.HeaderText, TextAnchor.MiddleCenter, true, 110f), true); var tt = UiKit.Title(UiKit.FillLabel(head, title, 44, UiKit.HeaderText, TextAnchor.MiddleCenter, true, 110f), true);
tt.resizeTextForBestFit = true; tt.resizeTextForBestFit = true;
tt.resizeTextMinSize = 28; tt.resizeTextMinSize = 28;
@ -694,8 +695,8 @@ namespace TKS.OutGame
StaminaModal(r ?? "군량 +" + e.GemStaminaAmount, r == null); StaminaModal(r ?? "군량 +" + e.GemStaminaAmount, r == null);
if (Map != null) Map.RefreshPopup(); if (Map != null) Map.RefreshPopup();
}); });
ExchangeRow(field, 1, 286f + 160f, w, "ad", "광고", e.AdStamina, "오늘 " + d.adsUsed.stamina + " / " + e.AdStaminaDaily + " · 광고 SDK 미연동(시험 지급)", ExchangeRow(field, 1, 286f + 160f, w, "ad", "광고", e.AdStamina, "오늘 " + d.adsUsed.stamina + " / " + e.AdStaminaDaily,
d.adsUsed.stamina < e.AdStaminaDaily, "btn_s_green", "보기", () => d.adsUsed.stamina < e.AdStaminaDaily, UISkin.Has("btn_green") ? "btn_green" : "btn_s_green", "보기", () =>
{ {
var r = Session.AdStamina(); var r = Session.AdStamina();
StaminaModal(r ?? "군량 +" + e.AdStamina, r == null); StaminaModal(r ?? "군량 +" + e.AdStamina, r == null);
@ -721,7 +722,7 @@ namespace TKS.OutGame
bt.horizontalOverflow = HorizontalWrapMode.Overflow; bt.horizontalOverflow = HorizontalWrapMode.Overflow;
UiKit.Label(row, note, 24, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(30f, -96f), new Vector2(w - 380f, 36f), false); UiKit.Label(row, note, 24, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(30f, -96f), new Vector2(w - 380f, 36f), false);
var btn = UiKit.SkinBtn(row, "Btn", can || !UISkin.Has("btn_gray") ? skin : "btn_gray", UiKit.White, label, 38, UiKit.White, w - Pad * 2f - 24f - 250f, 20f, 250f, 100f, onClick); var btn = UiKit.SkinBtn(row, "Btn", can || !UISkin.Has("btn_gray") ? skin : "btn_gray", UiKit.White, label, 38, UiKit.White, w - Pad * 2f - 24f - 250f, 20f, 250f, 100f, onClick);
if (skin == "btn_s_green" && can) UiKit.BtnCost(btn, "ad", "", 36f, 24); if (skin.Contains("green") && can) UiKit.BtnCost(btn, "ad", "", 36f, 24);
} }
// ---------- 월드맵 연결 ---------- // ---------- 월드맵 연결 ----------
@ -800,7 +801,7 @@ namespace TKS.OutGame
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;
} }
y += 140f; y += 128f;
if (lead.Count > 0) if (lead.Count > 0)
{ {
string names = string.Join(" · ", lead.ToArray()); string names = string.Join(" · ", lead.ToArray());

View File

@ -100,37 +100,37 @@ namespace TKS.OutGame
{ {
var g = S.Db.Gacha; var g = S.Db.Gacha;
// 배너 // 배너
var banner = UiKit.At(p, "Banner", 24f, 12f, 1032f, 470f); var banner = UiKit.At(p, "Banner", 24f, 12f, 1032f, 600f);
UiKit.Skin(banner, "banner", Color.white); UiKit.Skin(banner, "banner", Color.white);
if (UISkin.Has("banner_pattern")) if (UISkin.Has("banner_pattern"))
{ {
var pat = UiKit.Skin(UiKit.At(banner, "Pattern", 18f, 470f - 112f, 1032f - 36f, 90f), "banner_pattern", UiKit.Col("banner_pattern", Color.clear)); var pat = UiKit.Skin(UiKit.At(banner, "Pattern", 18f, 600f - 112f, 1032f - 36f, 90f), "banner_pattern", UiKit.Col("banner_pattern", Color.clear));
pat.type = Image.Type.Tiled; pat.type = Image.Type.Tiled;
} }
UiKit.InfoChip(banner, "Period", 30f, 26f, 220f, 52f, null, "픽업 · 2주", 28); UiKit.InfoChip(banner, "Period", 30f, 26f, 180f, 52f, null, "기간 2주", 28); // 「픽업」 = 오른쪽 위 뱃지 하나만(검수 결함 3)
UiKit.Title(UiKit.Label(banner, "영웅·유닛 뽑기", 60, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -100f), new Vector2(600f, 90f)), true); UiKit.Title(UiKit.Label(banner, "영웅·유닛 뽑기", 60, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -100f), new Vector2(600f, 90f)), true);
UiKit.Label(banner, "모든 영웅·병사 유닛\n= 뽑기로 획득", 32, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.UpperLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -200f), new Vector2(520f, 110f), false); UiKit.Label(banner, "모든 영웅·병사 유닛\n= 뽑기로 획득", 32, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.UpperLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(36f, -200f), new Vector2(520f, 110f), false);
var free = UiKit.Skin(UiKit.At(banner, "Free", 36f, 470f - 104f, 300f, 64f), "tail", UiKit.Col("tail_red", UiKit.Red)); var free = UiKit.Skin(UiKit.At(banner, "Free", 36f, 600f - 104f, 300f, 64f), "tail", UiKit.Col("tail_red", UiKit.Red));
UiKit.Title(UiKit.FillLabel(free.transform, "첫 10연 무료", 30, UiKit.White), true); UiKit.Title(UiKit.FillLabel(free.transform, "첫 10연 무료", 30, UiKit.White), true);
freeChip = free.gameObject; freeChip = free.gameObject;
pickupArt = UiKit.Rect("PickupArt", banner, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-20f, 22f), new Vector2(440f, 420f)); pickupArt = UiKit.Rect("PickupArt", banner, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-20f, 20f), new Vector2(560f, 560f));
var hot = UiKit.Icon(banner, "badge_hot", new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-34f, -30f), 120f); var hot = UiKit.Icon(banner, "badge_hot", new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-52f, -44f), 88f); // 배너 안쪽(검수 결함 3)
if (hot != null) if (hot != null)
{ {
UiKit.DropShadow(hot, 4f); UiKit.DropShadow(hot, 4f);
UiKit.Title(UiKit.FillLabel(hot.transform, "픽업", 30, UiKit.White), true); UiKit.Title(UiKit.FillLabel(hot.transform, "픽업", 24, UiKit.White), true);
} }
// 천장 게이지 // 천장 게이지
RectTransform pr; RectTransform pr;
var pf = UiKit.SectionPanel(p, "Pity", 24f, 504f, 1032f, 156f, false, false, out pr); var pf = UiKit.SectionPanel(p, "Pity", 24f, 632f, 1032f, 176f, false, false, out pr);
UiKit.Title(UiKit.Label(pf, "천장", 34, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(26f, -12f), new Vector2(200f, 50f)), true); UiKit.Title(UiKit.Label(pf, "천장", 34, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(26f, -12f), new Vector2(200f, 50f)), true);
pityText = UiKit.Label(pf, "", 28, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-26f, -12f), new Vector2(620f, 50f), false); pityText = UiKit.Label(pf, "", 28, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleRight, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-26f, -12f), new Vector2(620f, 50f), false);
pityBar = UiKit.Gauge(pf, "Gauge", 20f, 52f, GaugeW + 60f, "lv_badge_y", "lv_fill", out pityBadge); pityBar = UiKit.Gauge(pf, "Gauge", 20f, 62f, GaugeW + 60f, "lv_badge_y", "lv_fill", out pityBadge);
// 확률 공개 // 확률 공개
RectTransform probRoot; RectTransform probRoot;
var prob = UiKit.SectionPanel(p, "Prob", 24f, 682f, 1032f, 330f, false, false, out probRoot); var prob = UiKit.SectionPanel(p, "Prob", 24f, 828f, 1032f, 400f, false, false, out probRoot);
UiKit.SectionTitle(probRoot, "확률 공개"); UiKit.SectionTitle(probRoot, "확률 공개");
var info = UiKit.Rect("Info", probRoot, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-16f, -12f), new Vector2(64f, 64f)); var info = UiKit.Rect("Info", probRoot, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-16f, -12f), new Vector2(64f, 64f));
UiKit.Skin(info, "badge_circle", UiKit.Col("chip_dark", UiKit.Dark), true); UiKit.Skin(info, "badge_circle", UiKit.Col("chip_dark", UiKit.Dark), true);
@ -139,8 +139,8 @@ namespace TKS.OutGame
info.gameObject.AddComponent<Button>().onClick.AddListener(ShowGachaRules); info.gameObject.AddComponent<Button>().onClick.AddListener(ShowGachaRules);
for (int t = 3; t >= 1; t--) for (int t = 3; t >= 1; t--)
{ {
float y = 84f + (3 - t) * 74f; float y = 88f + (3 - t) * 98f;
var row = UiKit.Skin(UiKit.At(prob, "Row" + t, 20f, y, 1032f - 12f - 40f, 62f), "panel12", UiKit.Col("row_on_field", UiKit.Paper)).transform; var row = UiKit.Skin(UiKit.At(prob, "Row" + t, 20f, y, 1032f - 12f - 40f, 80f), "panel12", UiKit.Col("row_on_field", UiKit.Paper)).transform;
for (int s = 0; s < t; s++) for (int s = 0; s < t; s++)
{ {
var st = UiKit.Icon(row, "star_on", new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(40f + s * 40f, 0f), 40f); var st = UiKit.Icon(row, "star_on", new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(40f + s * 40f, 0f), 40f);
@ -154,9 +154,9 @@ namespace TKS.OutGame
} }
// 1회 · 10연 // 1회 · 10연
singleBtn = UiKit.SkinBtn(p, "Single", "btn_sky", UiKit.White, "1회", 42, UiKit.White, 24f, 1046f, 420f, 116f, () => DoDraw(1)); singleBtn = UiKit.SkinBtn(p, "Single", "btn_sky", UiKit.White, "1회", 42, UiKit.White, 24f, 1288f, 420f, 116f, () => DoDraw(1)); // 버튼 행 = 탭 바 위 24 고정(검수 결함 4)
singleCost = UiKit.BtnCost(singleBtn, "cur_gem", "", 44f, 36); singleCost = UiKit.BtnCost(singleBtn, "cur_gem", "", 44f, 36);
tenBtn = UiKit.SkinBtn(p, "Ten", "btn_l_yellow", UiKit.White, g.TenCount + "연", 46, UiKit.Col("text_on_yellow", UiKit.Ink), 1056f - 580f, 1040f, 580f, 122f, () => DoDraw(g.TenCount)); tenBtn = UiKit.SkinBtn(p, "Ten", "btn_l_yellow", UiKit.White, g.TenCount + "연", 46, UiKit.Col("text_on_yellow", UiKit.Ink), 1056f - 580f, 1282f, 580f, 122f, () => DoDraw(g.TenCount));
tenCost = UiKit.BtnCost(tenBtn, "cur_gem", "", 44f, 36); tenCost = UiKit.BtnCost(tenBtn, "cur_gem", "", 44f, 36);
var f2 = UiKit.Skin(UiKit.Rect("Free2", tenBtn.transform, new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(-14f, 2f), new Vector2(200f, 50f)), "tail", UiKit.Col("tail_red", UiKit.Red)); var f2 = UiKit.Skin(UiKit.Rect("Free2", tenBtn.transform, new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(-14f, 2f), new Vector2(200f, 50f)), "tail", UiKit.Col("tail_red", UiKit.Red));
UiKit.Title(UiKit.FillLabel(f2.transform, "첫 무료", 26, UiKit.White), true); UiKit.Title(UiKit.FillLabel(f2.transform, "첫 무료", 26, UiKit.White), true);
@ -269,6 +269,15 @@ namespace TKS.OutGame
var picks = new List<HeroDb.Hero>(); var picks = new List<HeroDb.Hero>();
foreach (var pe in g.pool) foreach (var pe in g.pool)
if (pe.pickup && pe.inPool && S.Def(pe.heroId) != null) picks.Add(S.Def(pe.heroId)); if (pe.pickup && pe.inPool && S.Def(pe.heroId) != null) picks.Add(S.Def(pe.heroId));
if (pityBadge != null)
{
var arts = picks.FindAll(h => UiKit.ArtSprite(h.art) != null);
for (int i = 0; i < arts.Count && i < 2; i++)
UiKit.Portrait("Pick" + i, pickupArt, arts[i], new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-10f - i * 250f, 70f), new Vector2(300f, 440f), false, 1f, new Color(1f, 1f, 1f, 0f));
for (int i = 0; i < picks.Count && i < 2; i++)
UiKit.InfoChip(pickupArt, "Name" + i, 560f - (i + 1) * 250f, 498f, 230f, 50f, null, picks[i].nameKo + " ★" + picks[i].rarity, 26);
return;
}
for (int i = 0; i < picks.Count && i < 2; i++) for (int i = 0; i < picks.Count && i < 2; i++)
{ {
UiKit.Portrait("Pick" + i, pickupArt, picks[i], new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-i * 210f, 50f), new Vector2(230f, 330f), false, 1f, new Color(1f, 1f, 1f, 0f)); UiKit.Portrait("Pick" + i, pickupArt, picks[i], new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-i * 210f, 50f), new Vector2(230f, 330f), false, 1f, new Color(1f, 1f, 1f, 0f));

View File

@ -376,7 +376,7 @@ namespace TKS.OutGame
} }
/// <summary>조건·정보 행(§4-2 · BasicFrame_Round12 panel_field · 좌 아이콘(tint = 켜짐 ok · 꺼짐 disabled) + 글자) · 왼쪽 위 기준 · icon null = 아이콘 없음.</summary> /// <summary>조건·정보 행(§4-2 · BasicFrame_Round12 panel_field · 좌 아이콘(tint = 켜짐 ok · 꺼짐 disabled) + 글자) · 왼쪽 위 기준 · icon null = 아이콘 없음.</summary>
public static Text CondRow(Transform p, string name, float x, float y, float w, float h, string icon, bool on, string text, int size, bool tint = true, string plate = "panel_field") public static Text CondRow(Transform p, string name, float x, float y, float w, float h, string icon, bool on, string text, int size, bool tint = true, string plate = "row_on_field")
{ {
var row = Skin(At(p, name, x, y, w, h), "panel12", Col(plate, Dark)); var row = Skin(At(p, name, x, y, w, h), "panel12", Col(plate, Dark));
float lx = 24f; float lx = 24f;

View File

@ -59,6 +59,10 @@ namespace TKS
Image skillGlow; Image skillGlow;
const float HpBarW = 360f; const float HpBarW = 360f;
/// <summary>결과 패널이 따로 있으면(아웃게임) 결과 단계에서 HUD 전체를 숨긴다(검수 결함 1 · 제목 2중 방지).</summary>
public bool HideOnResult;
CanvasGroup group;
Image minimapBg; Image minimapBg;
Image minimapView; Image minimapView;
readonly Dictionary<Unit, Image> minimapDots = new Dictionary<Unit, Image>(); readonly Dictionary<Unit, Image> minimapDots = new Dictionary<Unit, Image>();
@ -78,6 +82,7 @@ namespace TKS
scaler.referenceResolution = new Vector2(1080f, 1920f); scaler.referenceResolution = new Vector2(1080f, 1920f);
scaler.matchWidthOrHeight = 0.5f; scaler.matchWidthOrHeight = 0.5f;
gameObject.AddComponent<GraphicRaycaster>(); gameObject.AddComponent<GraphicRaycaster>();
group = gameObject.AddComponent<CanvasGroup>();
if (EventSystem.current == null && FindFirstObjectByType<EventSystem>() == null) if (EventSystem.current == null && FindFirstObjectByType<EventSystem>() == null)
{ {
@ -557,6 +562,7 @@ namespace TKS
} }
bool result = battle.Phase == BattlePhase.StageClear || battle.Phase == BattlePhase.Defeat; bool result = battle.Phase == BattlePhase.StageClear || battle.Phase == BattlePhase.Defeat;
if (group != null) group.alpha = HideOnResult && result ? 0f : 1f;
if (resultOverlay.activeSelf != result) resultOverlay.SetActive(result); if (resultOverlay.activeSelf != result) resultOverlay.SetActive(result);
if (result) if (result)
{ {

View File

@ -268,6 +268,7 @@ namespace TKS
Text popupSweepLabel; Text popupSweepLabel;
RectTransform popupField; RectTransform popupField;
Text popupCost; Text popupCost;
Text popupCode;
int popupNode = -1; int popupNode = -1;
RectTransform bannerRt; RectTransform bannerRt;
RectTransform prevRt; RectTransform prevRt;
@ -656,6 +657,11 @@ namespace TKS
for (int i = popupField.childCount - 1; i >= 0; i--) Destroy(popupField.GetChild(i).gameObject); for (int i = popupField.childCount - 1; i >= 0; i--) Destroy(popupField.GetChild(i).gameObject);
PopupFill(si, st == NodeState.Lock, popupField); PopupFill(si, st == NodeState.Lock, popupField);
popupGoLabel.text = st == NodeState.Lock ? "잠김" : st == NodeState.Clear ? "다시 출정" : "출정"; popupGoLabel.text = st == NodeState.Lock ? "잠김" : st == NodeState.Clear ? "다시 출정" : "출정";
if (popupCode != null)
{
popupCode.text = def.no + "-" + stage.stage + (stage.kind == StageKind.Boss ? " 보스" : stage.kind == StageKind.Elite ? " 정예" : "");
popupTitle.text = "제" + def.no + "장 " + def.title;
}
if (popupCost != null) popupCost.text = CostOf != null ? CostOf(si).ToString() : ""; if (popupCost != null) popupCost.text = CostOf != null ? CostOf(si).ToString() : "";
((RectTransform)popupGo.transform).anchoredPosition = new Vector2(sweep ? 390f : 240f, -PopupBtnY); ((RectTransform)popupGo.transform).anchoredPosition = new Vector2(sweep ? 390f : 240f, -PopupBtnY);
} }
@ -762,7 +768,7 @@ namespace TKS
// 팩 스테이지 팝업 배치(UI px · 패널 왼쪽 위 기준 · #1104) // 팩 스테이지 팝업 배치(UI px · 패널 왼쪽 위 기준 · #1104)
const float PopupW = 900f; const float PopupW = 900f;
const float PopupH = 1160f; const float PopupH = 1160f;
const float PopupBtnY = PopupH - 32f - 104f; const float PopupBtnY = PopupH - 52f - 104f;
void BuildPopup() void BuildPopup()
{ {
@ -811,7 +817,16 @@ namespace TKS
UISkin.Apply(field, "panel_field"); UISkin.Apply(field, "panel_field");
field.color = UISkin.Col("panel_field", Ink); field.color = UISkin.Col("panel_field", Ink);
field.rectTransform.offsetMin = new Vector2(20f, PopupH - PopupBtnY + 16f); field.rectTransform.offsetMin = new Vector2(20f, PopupH - PopupBtnY + 16f);
field.rectTransform.offsetMax = new Vector2(-20f, -166f); field.rectTransform.offsetMax = new Vector2(-20f, -126f);
// 제목 띠 = 공용 팝업과 같은 h110 · #1F2138 · 왼쪽 스테이지 칩(검수 결함 6)
var head = panel.transform.Find("Head") as RectTransform;
if (head != null)
{
head.sizeDelta = new Vector2(head.sizeDelta.x, 110f);
head.GetComponent<Image>().color = UISkin.Col("popup_band", Ink);
popupCode = TKS.OutGame.UiKit.InfoChip(head, "Code", 30f, 27f, 190f, 56f, null, "", 30);
popupTitle.fontSize = 40;
}
popupField = field.rectTransform; popupField = field.rectTransform;
popupGo = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Go", "btn_l_red", UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), "출정", 46, Color.white, 240f, PopupBtnY, 420f, 104f, ConfirmPopup); popupGo = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Go", "btn_l_red", UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), "출정", 46, Color.white, 240f, PopupBtnY, 420f, 104f, ConfirmPopup);
popupGoLabel = TKS.OutGame.UiKit.LabelOf(popupGo); popupGoLabel = TKS.OutGame.UiKit.LabelOf(popupGo);