From 10988e50c2137efa1456f4dec659d26e92490614 Mon Sep 17 00:00:00 2001 From: swrring Date: Wed, 9 Sep 2026 02:13:35 +0900 Subject: [PATCH] =?UTF-8?q?[WL-813tj]=20=EB=B3=B4=EC=8A=A4=20=EB=B0=B0?= =?UTF-8?q?=EB=84=88=20=C2=B7=20=EB=AC=BC=EC=95=BD/=EB=B6=80=ED=99=9C=20UI?= =?UTF-8?q?=20=C2=B7=20Safe=20Area=20=EC=8B=A4=ED=9A=A8=ED=99=94=20(#813)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgentScripts/WL813tj_Apply.cs | 384 +++ AgentScripts/WL813tj_Probe.cs | 476 ++++ Assets/Res_Addr/MainUI/NewGameUI.prefab | 2445 ++++++++++++++++- Assets/WL/UI/Scripts/BossBanner.cs | 447 +++ Assets/WL/UI/Scripts/BossBanner.cs.meta | 2 + Assets/WL/UI/Scripts/HitVignette.cs | 287 ++ Assets/WL/UI/Scripts/HitVignette.cs.meta | 2 + Assets/WL/UI/Scripts/PotionButton.cs | 333 +++ Assets/WL/UI/Scripts/PotionButton.cs.meta | 2 + Assets/WL/UI/Scripts/ReviveDialog.cs | 343 +++ Assets/WL/UI/Scripts/ReviveDialog.cs.meta | 2 + Assets/WL/UI/Scripts/WLBattlePadLayout.cs | 11 +- Assets/WL/UI/Scripts/WLIngameUiOverride.cs | 24 +- Assets/WL/UI/Scripts/WLVignetteUtil.cs | 245 ++ Assets/WL/UI/Scripts/WLVignetteUtil.cs.meta | 2 + .../Resources/WL/WLBossUiSettings.asset | 37 + .../Resources/WL/WLBossUiSettings.asset.meta | 8 + .../Resources/WL/WLSurvivalUiSettings.asset | 51 + .../WL/WLSurvivalUiSettings.asset.meta | 8 + Assets/WL/UI/Settings/WLBossUiSettings.cs | 111 + .../WL/UI/Settings/WLBossUiSettings.cs.meta | 2 + Assets/WL/UI/Settings/WLSurvivalUiSettings.cs | 143 + .../UI/Settings/WLSurvivalUiSettings.cs.meta | 2 + 23 files changed, 5337 insertions(+), 30 deletions(-) create mode 100644 AgentScripts/WL813tj_Apply.cs create mode 100644 AgentScripts/WL813tj_Probe.cs create mode 100644 Assets/WL/UI/Scripts/BossBanner.cs create mode 100644 Assets/WL/UI/Scripts/BossBanner.cs.meta create mode 100644 Assets/WL/UI/Scripts/HitVignette.cs create mode 100644 Assets/WL/UI/Scripts/HitVignette.cs.meta create mode 100644 Assets/WL/UI/Scripts/PotionButton.cs create mode 100644 Assets/WL/UI/Scripts/PotionButton.cs.meta create mode 100644 Assets/WL/UI/Scripts/ReviveDialog.cs create mode 100644 Assets/WL/UI/Scripts/ReviveDialog.cs.meta create mode 100644 Assets/WL/UI/Scripts/WLVignetteUtil.cs create mode 100644 Assets/WL/UI/Scripts/WLVignetteUtil.cs.meta create mode 100644 Assets/WL/UI/Settings/Resources/WL/WLBossUiSettings.asset create mode 100644 Assets/WL/UI/Settings/Resources/WL/WLBossUiSettings.asset.meta create mode 100644 Assets/WL/UI/Settings/Resources/WL/WLSurvivalUiSettings.asset create mode 100644 Assets/WL/UI/Settings/Resources/WL/WLSurvivalUiSettings.asset.meta create mode 100644 Assets/WL/UI/Settings/WLBossUiSettings.cs create mode 100644 Assets/WL/UI/Settings/WLBossUiSettings.cs.meta create mode 100644 Assets/WL/UI/Settings/WLSurvivalUiSettings.cs create mode 100644 Assets/WL/UI/Settings/WLSurvivalUiSettings.cs.meta diff --git a/AgentScripts/WL813tj_Apply.cs b/AgentScripts/WL813tj_Apply.cs new file mode 100644 index 000000000..82375e6cd --- /dev/null +++ b/AgentScripts/WL813tj_Apply.cs @@ -0,0 +1,384 @@ +// WL-813tj (#813) — ① 설정 에셋 2종 생성 ② NewGameUI Safe Area 실효화(5레이어 재부모화) +// ③ 보스 배너 · 피격 비네트 · 부활 팝업 · 물약 버튼 노드 추가 +// 실행: +// unity command run_script --file AgentScripts/WL813tj_Apply.cs --entry WL813tj_Apply.CreateSettings +// unity command run_script --file AgentScripts/WL813tj_Apply.cs --entry WL813tj_Apply.Resave +// unity command run_script --file AgentScripts/WL813tj_Apply.cs --entry WL813tj_Apply.ApplySafeArea +// unity command run_script --file AgentScripts/WL813tj_Apply.cs --entry WL813tj_Apply.ApplyUi +// unity command run_script --file AgentScripts/WL813tj_Apply.cs --entry WL813tj_Apply.Revert +// 🔴 run_script 파일은 파일마다 독립 어셈블리 — 다른 AgentScript 상수 참조 불가(813c 교훈). +// +// ■ Safe Area 를 패널 **2개**로 나누는 이유 (실측 근거 · 완료보고 ⓒ) +// NewGameUI 캔버스 직속 12레이어에는 Canvas/sortingOrder 가 하나도 없다(실측: 5레이어 전부 컴포넌트 1~2개, +// Canvas 0개) → **그리는 순서 = 형제 순서**다. 대상 5레이어는 원본에서 +// Common(4) · LobbyUIs(5) < IngameUIs(6) · FarmUIs(7) < MessageInfo(8) · Center(9) · PopupMgr(10) < TestMapUIMgr(11) +// 로 **IngameUIs/FarmUIs 를 사이에 끼고 앞뒤로 갈라져 있다**. 5개를 패널 하나에 몰면 앞뒤 관계가 뒤집힌다 +// (로비 UI 가 인게임 UI 위로 올라오거나, 팝업이 인게임 UI 아래로 내려간다). +// 그래서 Back(Common·LobbyUIs) / Front(MessageInfo·Center·PopupMgr) 두 패널을 원래 자리에 끼워 +// **평탄화하면 원본과 완전히 같은 순서**가 되게 했다. + +using System.Text; +using UnityEditor; +using UnityEngine; + +public static class WL813tj_Apply +{ + public const string NewGameUIPath = "Assets/Res_Addr/MainUI/NewGameUI.prefab"; + public const string SettingsDir = "Assets/WL/UI/Settings/Resources/WL"; + public const string BossSettingsPath = SettingsDir + "/WLBossUiSettings.asset"; + public const string SurvivalSettingsPath = SettingsDir + "/WLSurvivalUiSettings.asset"; + + public const string BackPanel = "WL_SafeArea_Back"; + public const string FrontPanel = "WL_SafeArea_Front"; + public static readonly string[] BackLayers = { "Common", "LobbyUIs" }; + public static readonly string[] FrontLayers = { "MessageInfo", "Center", "PopupMgr" }; + + public const string HudPath = "IngameUIs/WL_HUD"; + public const string PadPath = "IngameUIs/BattleUI"; + public const string BannerName = "WL_BossBanner"; + public const string HitName = "WL_HitVignette"; + public const string ReviveName = "WL_ReviveDialog"; + public const string PotionName = "WL_PotionButton"; + const string TmpFontGuid = "a387e325271126742ad15569dba1ac57"; // 813c/813g 가 실측한 원본 TMP 폰트 + const int UILayer = 5; + + // ── 유틸 ───────────────────────────────────────────────────────────────── + static Transform FindByPath(Transform root, string path) + { + var cur = root; + foreach (var part in path.Split('/')) + { + Transform next = null; + for (int i = 0; i < cur.childCount; i++) + if (cur.GetChild(i).name == part) { next = cur.GetChild(i); break; } + if (next == null) return null; + cur = next; + } + return cur; + } + + static Transform FindAnywhere(Transform root, string name) + { + for (int i = 0; i < root.childCount; i++) + { + var c = root.GetChild(i); + if (c.name == name) return c; + for (int j = 0; j < c.childCount; j++) + if (c.GetChild(j).name == name) return c.GetChild(j); + } + return null; + } + + static void EnsureFolder(string dir) + { + var parts = dir.Split('/'); + var cur = parts[0]; + for (int i = 1; i < parts.Length; i++) + { + var next = cur + "/" + parts[i]; + if (!AssetDatabase.IsValidFolder(next)) AssetDatabase.CreateFolder(cur, parts[i]); + cur = next; + } + } + + static RectTransform EnsureNode(Transform parent, string name, StringBuilder sb) + { + var t = parent.Find(name) as RectTransform; + if (t == null) + { + var go = new GameObject(name, typeof(RectTransform)); + go.layer = UILayer; + t = (RectTransform)go.transform; + t.SetParent((RectTransform)parent, false); + sb.AppendLine(" " + parent.name + "/" + name + " : 노드 추가"); + } + else sb.AppendLine(" " + parent.name + "/" + name + " : 이미 있음"); + return t; + } + + static TMPro.TMP_FontAsset LoadFont(StringBuilder sb) + { + var p = AssetDatabase.GUIDToAssetPath(TmpFontGuid); + var f = string.IsNullOrEmpty(p) ? null : AssetDatabase.LoadAssetAtPath(p); + sb.AppendLine("폰트: " + (f != null ? p : "「미확인」 — TMP 기본 폰트로 떨어진다")); + return f; + } + + // ── ① 설정 에셋 ────────────────────────────────────────────────────────── + /// 설정 에셋 2종 생성(이미 있으면 값 유지 · 덮어쓰지 않는다). + public static object CreateSettings() + { + var sb = new StringBuilder(); + EnsureFolder(SettingsDir); + + var boss = AssetDatabase.LoadAssetAtPath(BossSettingsPath); + if (boss == null) + { + boss = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(boss, BossSettingsPath); + sb.AppendLine("생성: " + BossSettingsPath); + } + else sb.AppendLine("이미 있음(값 유지): " + BossSettingsPath); + + var sur = AssetDatabase.LoadAssetAtPath(SurvivalSettingsPath); + if (sur == null) + { + sur = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(sur, SurvivalSettingsPath); + sb.AppendLine("생성: " + SurvivalSettingsPath); + } + else sb.AppendLine("이미 있음(값 유지): " + SurvivalSettingsPath); + + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + WL.UI.WLBossUiSettings.ClearCache(); + WL.UI.WLSurvivalUiSettings.ClearCache(); + + sb.AppendLine("── 813t 보스 배너(기준서 §D-1 813t)"); + sb.AppendLine(" banner=" + boss.bannerSeconds + "s topPx=" + boss.bannerTopMarginPx + " sizePx=" + boss.bannerSizePx + + " title=\"" + boss.bannerTitleText + "\" punch=" + boss.bannerPunchScale); + sb.AppendLine(" warn=" + boss.warnVignetteSeconds + "s thickPx=" + boss.warnVignetteThicknessPx + + " pulses=" + boss.warnVignettePulses + " color=" + boss.warnVignetteColor); + sb.AppendLine("── 813j 생존 UI(기준서 §D-1 813j · §B 요소 8)"); + sb.AppendLine(" 물약 slot=" + sur.potionReserveSlotIndex + " fallback(count=" + sur.potionFallbackCount + + " cd=" + sur.potionFallbackCooldownSeconds + "s) requireProvider=" + sur.potionRequireProvider); + sb.AppendLine(" 부활 delay=" + sur.reviveDelaySeconds + "s 공용팝업=" + sur.reviveUseCommonPopup + + " msg=\"" + sur.reviveMessage + "\" 비용=\"" + sur.reviveCostText + "\""); + sb.AppendLine(" 피격 border=" + sur.hitBorderSeconds + "s/" + sur.hitBorderThicknessPx + "px target=" + sur.hitBorderTargetPath + + " 무적무시=" + sur.ignoreInvincibleHits + " 스로틀=" + sur.hitMinIntervalSeconds + "s"); + return sb.ToString(); + } + + /// 무변경 재저장 — 프리팹 편집 전에 재직렬화 diff 가 생기는지 먼저 잰다(802b·813c 교훈). + public static object Resave() + { + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try { PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath); } + finally { PrefabUtility.UnloadPrefabContents(root); } + AssetDatabase.Refresh(); + return NewGameUIPath + " : 무변경 재저장 (git diff 로 재직렬화 여부 확인)"; + } + + // ── ② Safe Area 실효화 ─────────────────────────────────────────────────── + static RectTransform MakePanel(Transform root, string name, int siblingIndex, StringBuilder sb) + { + var t = root.Find(name) as RectTransform; + if (t == null) + { + var go = new GameObject(name, typeof(RectTransform)); + go.layer = UILayer; + t = (RectTransform)go.transform; + t.SetParent((RectTransform)root, false); + sb.AppendLine(name + " : 패널 추가"); + } + else sb.AppendLine(name + " : 이미 있음"); + + t.anchorMin = Vector2.zero; t.anchorMax = Vector2.one; + t.offsetMin = Vector2.zero; t.offsetMax = Vector2.zero; + t.pivot = new Vector2(0.5f, 0.5f); + t.localScale = Vector3.one; + t.localPosition = new Vector3(0f, 0f, 0f); + if (t.GetComponent() == null) + { + t.gameObject.AddComponent(); + sb.AppendLine(" SafeAreaFitter 부착"); + } + if (siblingIndex >= 0) t.SetSiblingIndex(Mathf.Min(siblingIndex, root.childCount - 1)); + return t; + } + + public static object ApplySafeArea() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try + { + var rt = root.transform; + sb.AppendLine("── 적용 전 캔버스 루트 순서"); + sb.AppendLine(" " + Order(rt)); + + // Back 패널 = 원래 Common 이 있던 자리 + int backAt = IndexOf(rt, BackLayers[0]); + if (backAt < 0) return "🔴 " + BackLayers[0] + " 없음 — 중단"; + var back = MakePanel(rt, BackPanel, backAt, sb); + foreach (var n in BackLayers) Reparent(rt, n, back, sb); + + // Front 패널 = 원래 MessageInfo 가 있던 자리(Back 이동으로 인덱스가 당겨진 뒤 다시 잰다) + int frontAt = IndexOf(rt, FrontLayers[0]); + if (frontAt < 0) return "🔴 " + FrontLayers[0] + " 없음 — 중단"; + var front = MakePanel(rt, FrontPanel, frontAt, sb); + foreach (var n in FrontLayers) Reparent(rt, n, front, sb); + + sb.AppendLine("── 적용 후 캔버스 루트 순서(children=" + rt.childCount + ")"); + sb.AppendLine(" " + Order(rt)); + sb.AppendLine("── 평탄화(패널을 펼친 순서) = 원본과 같아야 한다"); + sb.AppendLine(" " + Flatten(rt)); + + PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath); + } + finally { PrefabUtility.UnloadPrefabContents(root); } + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return sb.ToString(); + } + + static int IndexOf(Transform parent, string name) + { + for (int i = 0; i < parent.childCount; i++) if (parent.GetChild(i).name == name) return i; + return -1; + } + + static void Reparent(Transform root, string name, RectTransform panel, StringBuilder sb) + { + var t = root.Find(name) as RectTransform; + if (t == null) + { + if (panel.Find(name) != null) { sb.AppendLine(" " + name + " : 이미 " + panel.name + " 아래"); return; } + sb.AppendLine(" 🔴 " + name + " 없음"); + return; + } + var before = new { a0 = t.anchorMin, a1 = t.anchorMax, p = t.anchoredPosition, s = t.sizeDelta, sc = t.localScale, z = t.localPosition.z, pv = t.pivot }; + t.SetParent(panel, false); // worldPositionStays=false → 로컬 값 그대로 보존 + t.SetAsLastSibling(); + bool same = before.a0 == t.anchorMin && before.a1 == t.anchorMax && before.p == t.anchoredPosition && + before.s == t.sizeDelta && before.sc == t.localScale && Mathf.Approximately(before.z, t.localPosition.z) && + before.pv == t.pivot; + sb.AppendLine(" " + name + " → " + panel.name + " (보존=" + same + " aMin" + t.anchorMin + " aMax" + t.anchorMax + + " off" + t.offsetMin + t.offsetMax + " scale" + t.localScale + " z=" + t.localPosition.z + ")"); + } + + static string Order(Transform t) + { + var sb = new StringBuilder(); + for (int i = 0; i < t.childCount; i++) { if (i > 0) sb.Append(" · "); sb.Append(i).Append(':').Append(t.GetChild(i).name); } + return sb.ToString(); + } + + static string Flatten(Transform t) + { + var sb = new StringBuilder(); + int k = 0; + for (int i = 0; i < t.childCount; i++) + { + var c = t.GetChild(i); + if (c.name.StartsWith("WL_SafeArea")) + { + for (int j = 0; j < c.childCount; j++) { if (k++ > 0) sb.Append(" · "); sb.Append(c.GetChild(j).name); } + } + else { if (k++ > 0) sb.Append(" · "); sb.Append(c.name); } + } + return sb.ToString(); + } + + // ── ③ UI 노드 ──────────────────────────────────────────────────────────── + public static object ApplyUi() + { + var sb = new StringBuilder(); + var boss = AssetDatabase.LoadAssetAtPath(BossSettingsPath); + var sur = AssetDatabase.LoadAssetAtPath(SurvivalSettingsPath); + if (boss == null || sur == null) return "🔴 설정 에셋 없음 — CreateSettings 먼저"; + var font = LoadFont(sb); + + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try + { + // ── 813t + 813j 화면 연출 = IngameUIs/WL_HUD (802b SafeAreaFitter 갈래 · 813c/813g 규칙) + var hud = FindByPath(root.transform, HudPath); + if (hud == null) sb.AppendLine("🔴 " + HudPath + " 없음"); + else + { + var banner = EnsureNode(hud, BannerName, sb); + var bc = banner.GetComponent(); + if (bc == null) { bc = banner.gameObject.AddComponent(); sb.AppendLine(" BossBanner 추가"); } + if (font != null) bc.SetFont(font); + sb.AppendLine(" build made=" + bc.BuildIfNeeded() + " · " + bc.ApplyLayout()); + bc.HideNow(); + + var hit = EnsureNode(hud, HitName, sb); + var hc = hit.GetComponent(); + if (hc == null) { hc = hit.gameObject.AddComponent(); sb.AppendLine(" HitVignette 추가"); } + sb.AppendLine(" build made=" + hc.BuildIfNeeded() + " · " + hc.ApplyLayout()); + hc.HideNow(); // HP 바 테두리는 런타임(EnsureBorder)에서 만든다 = 프리팹 diff 0 + + var rev = EnsureNode(hud, ReviveName, sb); + var rc = rev.GetComponent(); + if (rc == null) { rc = rev.gameObject.AddComponent(); sb.AppendLine(" ReviveDialog 추가"); } + if (font != null) rc.SetFont(font); + sb.AppendLine(" build made=" + rc.BuildIfNeeded() + " · " + rc.ApplyLayout()); + rc.HideNow(); + rev.SetAsLastSibling(); // 폴백 팝업은 HUD 최상단 + } + + // ── 813j 물약 버튼 = IngameUIs/BattleUI 의 813c 예약 슬롯 자리 + var pad = FindByPath(root.transform, PadPath); + if (pad == null) sb.AppendLine("🔴 " + PadPath + " 없음"); + else + { + var pot = EnsureNode(pad, PotionName, sb); + var pc = pot.GetComponent(); + if (pc == null) { pc = pot.gameObject.AddComponent(); sb.AppendLine(" PotionButton 추가"); } + if (font != null) pc.SetFont(font); + sb.AppendLine(" build made=" + pc.BuildIfNeeded() + " · " + pc.ApplyLayout()); + sb.AppendLine(" refresh " + pc.Refresh()); + } + + PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath); + } + finally { PrefabUtility.UnloadPrefabContents(root); } + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return sb.ToString(); + } + + // ── 롤백 ───────────────────────────────────────────────────────────────── + public static object Revert() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try + { + // UI 노드 + var hud = FindByPath(root.transform, HudPath); + if (hud != null) + foreach (var n in new[] { BannerName, HitName, ReviveName }) + { + var t = hud.Find(n); + if (t != null) { Object.DestroyImmediate(t.gameObject); sb.AppendLine(HudPath + "/" + n + " : 제거"); } + } + var pad = FindByPath(root.transform, PadPath); + if (pad != null) + { + var t = pad.Find(PotionName); + if (t != null) { Object.DestroyImmediate(t.gameObject); sb.AppendLine(PadPath + "/" + PotionName + " : 제거"); } + } + + // Safe Area 패널 — 자식을 원래 자리로 되돌리고 패널을 지운다 + var rt = root.transform; + RestorePanel(rt, BackPanel, sb); + RestorePanel(rt, FrontPanel, sb); + sb.AppendLine("복원 후 순서: " + Order(rt)); + + PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath); + } + finally { PrefabUtility.UnloadPrefabContents(root); } + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return sb.ToString(); + } + + static void RestorePanel(Transform root, string panelName, StringBuilder sb) + { + var panel = root.Find(panelName) as RectTransform; + if (panel == null) { sb.AppendLine(panelName + " : 없음"); return; } + int at = panel.GetSiblingIndex(); + while (panel.childCount > 0) + { + var c = panel.GetChild(0) as RectTransform; + c.SetParent(root as RectTransform, false); + c.SetSiblingIndex(at++); + sb.AppendLine(" " + c.name + " : 루트로 복원 @" + (at - 1)); + } + Object.DestroyImmediate(panel.gameObject); + sb.AppendLine(panelName + " : 패널 제거"); + } +} diff --git a/AgentScripts/WL813tj_Probe.cs b/AgentScripts/WL813tj_Probe.cs new file mode 100644 index 000000000..dc521b4b9 --- /dev/null +++ b/AgentScripts/WL813tj_Probe.cs @@ -0,0 +1,476 @@ +// WL-813tj (#813) — 실측 프로브(Play 0 · 에디트 모드). +// unity command run_script --file AgentScripts/WL813tj_Probe.cs --entry WL813tj_Probe.DumpSafeArea +// unity command run_script --file AgentScripts/WL813tj_Probe.cs --entry WL813tj_Probe.DumpBoss +// unity command run_script --file AgentScripts/WL813tj_Probe.cs --entry WL813tj_Probe.DumpSurvival +// unity command run_script --file AgentScripts/WL813tj_Probe.cs --entry WL813tj_Probe.DumpPrefab +// 🔴 프리팹은 LoadPrefabContents 로 열고 **저장하지 않는다**(검증만). 구독은 전부 되돌린다. + +using System.Text; +using UnityEditor; +using UnityEngine; + +public static class WL813tj_Probe +{ + public const string NewGameUIPath = "Assets/Res_Addr/MainUI/NewGameUI.prefab"; + public const string HudPath = "IngameUIs/WL_HUD"; + public const string PadPath = "IngameUIs/BattleUI"; + + static Transform FindByPath(Transform root, string path) + { + var cur = root; + foreach (var part in path.Split('/')) + { + Transform next = null; + for (int i = 0; i < cur.childCount; i++) + if (cur.GetChild(i).name == part) { next = cur.GetChild(i); break; } + if (next == null) return null; + cur = next; + } + return cur; + } + + static void Save(string file, string body) + { + try { System.IO.File.WriteAllText(System.IO.Path.Combine("Logs", file), body); } catch { } + } + + // ═══ ⓒ Safe Area ════════════════════════════════════════════════════════ + struct Res { public string name; public int w, h; public Rect safe; public string src; } + + static Res[] QaResolutions() + { + // QA 5종(802b·813c 와 같은 목록). safeArea 는 「추정」 — 실기 인셋은 빌드 전까지 확인 불가(C23). + return new[] + { + new Res { name="1080x1920", w=1080, h=1920, safe=new Rect(0, 0, 1080, 1920), src="노치 없음(전체)" }, + new Res { name="720x1600", w= 720, h=1600, safe=new Rect(0, 0, 720, 1600), src="노치 없음(전체)" }, + new Res { name="1440x3200", w=1440, h=3200, safe=new Rect(0, 0, 1440, 3200), src="노치 없음(전체)" }, + new Res { name="1179x2556", w=1179, h=2556, safe=new Rect(0, 102, 1179, 2277), src="다이내믹 아일랜드 「추정」 top 177 / bottom 102 px" }, + new Res { name="1080x2400", w=1080, h=2400, safe=new Rect(0, 0, 1080, 2310), src="펀치홀 「추정」 top 90 px" }, + }; + } + + /// SafeAreaFitter.Apply 와 **같은 4줄**을 재현한다(Screen.safeArea 를 주입할 수 없어서). + static void FitterMath(Rect safe, int w, int h, bool applyH, bool applyV, out Vector2 min, out Vector2 max) + { + min = new Vector2(safe.xMin / w, safe.yMin / h); + max = new Vector2(safe.xMax / w, safe.yMax / h); + if (!applyH) { min.x = 0f; max.x = 1f; } + if (!applyV) { min.y = 0f; max.y = 1f; } + } + + public static object DumpSafeArea() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try + { + var rt = root.transform; + sb.AppendLine("[1] 캔버스 루트 순서 (children=" + rt.childCount + ")"); + for (int i = 0; i < rt.childCount; i++) + { + var c = rt.GetChild(i); + var crt = c as RectTransform; + bool panel = c.name.StartsWith("WL_SafeArea"); + sb.AppendLine(" [" + i + "] " + c.name + (panel ? " ← Safe Area 패널" : "") + + " active=" + c.gameObject.activeSelf + + (crt != null ? " aMin" + crt.anchorMin + " aMax" + crt.anchorMax + + " off" + crt.offsetMin + crt.offsetMax + " scale" + crt.localScale : "")); + if (!panel) continue; + var f = c.GetComponent(); + sb.AppendLine(" SafeAreaFitter=" + (f != null) + " Graphic=" + (c.GetComponent() != null) + + " comps=" + c.GetComponents().Length); + for (int j = 0; j < c.childCount; j++) + { + var g = c.GetChild(j) as RectTransform; + sb.AppendLine(" └ " + c.GetChild(j).name + " aMin" + g.anchorMin + " aMax" + g.anchorMax + + " off" + g.offsetMin + g.offsetMax + " scale" + g.localScale + " z=" + g.localPosition.z + + " active=" + g.gameObject.activeSelf); + } + } + + sb.AppendLine(); + sb.AppendLine("[2] 평탄화 순서(그리는 순서) = 원본과 같아야 회귀 0"); + var flat = new StringBuilder(); + for (int i = 0; i < rt.childCount; i++) + { + var c = rt.GetChild(i); + if (c.name.StartsWith("WL_SafeArea")) for (int j = 0; j < c.childCount; j++) flat.Append(c.GetChild(j).name).Append(" · "); + else flat.Append(c.name).Append(" · "); + } + sb.AppendLine(" 지금 : " + flat.ToString().TrimEnd(' ', '·')); + sb.AppendLine(" 원본 : New Image · Camera · Floating Joystick · CamRot · Common · LobbyUIs · IngameUIs · FarmUIs · MessageInfo · Center · PopupMgr · TestMapUIMgr"); + + sb.AppendLine(); + sb.AppendLine("[3] SafeAreaFitter 산식 표 (QA 5해상도 · applyH=applyV=true)"); + sb.AppendLine(" ※ Screen.safeArea 를 주입할 수 없어 SafeAreaFitter.Apply 의 4줄을 그대로 재현했다(802b 와 같은 방법)."); + sb.AppendLine(" 해상도 | safeArea(x,y,w,h) | anchorMin | anchorMax | 화면 인셋(px) | 근거"); + foreach (var r in QaResolutions()) + { + Vector2 mn, mx; + FitterMath(r.safe, r.w, r.h, true, true, out mn, out mx); + float insetTop = r.h - r.safe.yMax, insetBottom = r.safe.yMin; + sb.AppendLine(" " + r.name.PadRight(12) + "| " + + ("(" + r.safe.x + "," + r.safe.y + "," + r.safe.width + "," + r.safe.height + ")").PadRight(25) + "| " + + ("(" + mn.x.ToString("F4") + ", " + mn.y.ToString("F4") + ")").PadRight(17) + "| " + + ("(" + mx.x.ToString("F4") + ", " + mx.y.ToString("F4") + ")").PadRight(17) + "| " + + ("top " + insetTop + " / bottom " + insetBottom).PadRight(22) + "| " + r.src); + } + sb.AppendLine(" offsetMin/offsetMax 는 언제나 (0,0) — 패널은 앵커만 움직인다(802b 와 동일)."); + + // 실측 1건: 에디터가 보고하는 실제 Screen 으로 진짜 컴포넌트를 돌려 재현식과 대조한다. + sb.AppendLine(); + sb.AppendLine("[4] 실측 대조 1건 — 에디터 Screen(" + Screen.width + "x" + Screen.height + ") safeArea=" + Screen.safeArea); + foreach (var pn in new[] { "WL_SafeArea_Back", "WL_SafeArea_Front" }) + { + var p = rt.Find(pn) as RectTransform; + if (p == null) { sb.AppendLine(" " + pn + " 없음"); continue; } + var f = p.GetComponent(); + if (f == null) { sb.AppendLine(" " + pn + " SafeAreaFitter 없음"); continue; } + f.Apply(); + Vector2 mn, mx; + FitterMath(Screen.safeArea, Screen.width, Screen.height, true, true, out mn, out mx); + sb.AppendLine(" " + pn + " 실제 Apply → aMin" + p.anchorMin + " aMax" + p.anchorMax + + " off" + p.offsetMin + p.offsetMax + " | 재현식 aMin(" + mn.x.ToString("F4") + ", " + mn.y.ToString("F4") + + ") aMax(" + mx.x.ToString("F4") + ", " + mx.y.ToString("F4") + ") | 일치=" + + (Vector2.Distance(p.anchorMin, mn) < 1e-5f && Vector2.Distance(p.anchorMax, mx) < 1e-5f)); + // 검증만 — 프리팹은 저장하지 않는다 + } + + sb.AppendLine(); + sb.AppendLine("[5] 회귀 — WLIngameUiOverride 경로(설정 에셋의 옛 문자열이 그대로 먹는가)"); + var gs = WL.Settings.WLGameplaySettings.Instance; + if (gs == null) sb.AppendLine(" WLGameplaySettings 에셋 없음"); + else + { + foreach (var p in gs.ingameHideCanvasGroupPaths ?? new string[0]) + { + var t = WL.UI.WLVignetteUtil.FindUiPath(rt, p); + sb.AppendLine(" [canvasGroupHide] \"" + p + "\" → " + (t == null ? "🔴 없음" : "OK " + FullPath(rt, t))); + } + foreach (var p in gs.battlePadPaths ?? new string[0]) + { + var t = WL.UI.WLVignetteUtil.FindUiPath(rt, p); + sb.AppendLine(" [battlePad] \"" + p + "\" → " + (t == null ? "🔴 없음" : "OK " + FullPath(rt, t) + " children=" + t.childCount)); + } + var ui = root.GetComponent(); + var common = (ui != null && ui.gos != null && ui.gos.Length > 0) ? ui.gos[0] : null; + sb.AppendLine(" [gos[0]] NewGameUI.gos[0]=" + (common == null ? "🔴 null" : common.name + " (참조 · 재부모화 무관) 부모=" + + (common.transform.parent != null ? common.transform.parent.name : "-"))); + if (common != null) + foreach (var n in gs.ingameHideCommonObjectNames ?? new string[0]) + sb.AppendLine(" [commonHide] \"" + n + "\" → " + (common.transform.Find(n) == null ? "🔴 없음" : "OK")); + sb.AppendLine(" hideBattlePad=" + gs.hideBattlePad + " (읽기만 · S 소유 · 값 전환은 Lead)"); + } + + // 813j 피격 테두리 대상도 같은 탐색기로 확인 + var sur = WL.UI.WLSurvivalUiSettings.Instance; + if (sur != null) + { + var t = WL.UI.WLVignetteUtil.FindUiPath(rt, sur.hitBorderTargetPath); + sb.AppendLine(" [hitBorderTarget] \"" + sur.hitBorderTargetPath + "\" → " + + (t == null ? "🔴 없음" : "OK " + FullPath(rt, t) + + " size" + ((RectTransform)t).sizeDelta)); + } + } + finally { PrefabUtility.UnloadPrefabContents(root); } + var body = sb.ToString(); + Save("WL813tj_probe_safearea.txt", body); + return body; + } + + static string FullPath(Transform root, Transform t) + { + var sb = new StringBuilder(t.name); + var cur = t.parent; + while (cur != null && cur != root) { sb.Insert(0, cur.name + "/"); cur = cur.parent; } + return sb.ToString(); + } + + // ═══ ⓑ 813t 보스 배너 · 경고 비네트 ═════════════════════════════════════ + public static object DumpBoss() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + WL.UI.BossBanner bc = null; + try + { + var hud = FindByPath(root.transform, HudPath); + var node = hud != null ? hud.Find(WL813tj_ApplyNames.Banner) : null; + if (node == null) return "🔴 " + HudPath + "/" + WL813tj_ApplyNames.Banner + " 없음 — Apply 먼저"; + bc = node.GetComponent(); + if (bc == null) return "🔴 BossBanner 컴포넌트 없음"; + + sb.AppendLine("[0] 초기화 — 런타임과 같은 경로(OnEnable→Initialize)"); + sb.AppendLine(" 구독 전 Spawned=" + WL.Combat.Core.CombatEvents.Spawned.Count + + " BossPhase=" + WL.Combat.Boss.BossEvents.BossPhase.Count); + sb.AppendLine(" " + bc.Initialize()); + sb.AppendLine(" 구독 후 Spawned=" + WL.Combat.Core.CombatEvents.Spawned.Count + + " BossPhase=" + WL.Combat.Boss.BossEvents.BossPhase.Count); + float t0 = Time.unscaledTime; + + sb.AppendLine(); + sb.AppendLine("[1] 비보스 스폰 → 반응 없음(미표시 규칙)"); + sb.AppendLine(" " + WL.UI.BossBanner.RaiseFakeNonBossSpawned()); + bc.Tick(t0); + sb.AppendLine(" visible=" + bc.Visible + " shows=" + bc.ShowCount + " (기대 False / 0)"); + + sb.AppendLine(); + sb.AppendLine("[2] 보스 스폰(CombatEvents.Spawned isBoss=true) → 배너 + 비네트"); + sb.AppendLine(" " + WL.UI.BossBanner.RaiseFakeBossSpawned()); + var s = WL.UI.WLBossUiSettings.Instance; + float[] marks = { 0f, 0.05f, 0.15f, 0.20f, 0.40f, 0.79f, 0.81f, 1.0f, 1.19f, 1.21f }; + sb.AppendLine(" t(s) | 배너α | 배너scale | 경고α | 상태"); + foreach (var m in marks) + { + bc.Tick(t0 + m); + string state = (m < s.bannerSeconds ? "배너 " : "배너끝 ") + (m < s.warnVignetteSeconds ? "· 비네트" : "· 비네트끝"); + sb.AppendLine(" " + m.ToString("F2").PadLeft(5) + " | " + bc.BannerAlpha.ToString("F3") + + " | " + bc.BannerScale.ToString("F3").PadLeft(8) + + " | " + bc.WarnAlpha.ToString("F3") + " | " + state); + } + sb.AppendLine(" shows=" + bc.ShowCount + " seen(Spawned/보스/Phase)=" + bc.SpawnedSeen + "/" + bc.BossSpawnSeen + "/" + bc.PhaseSeen); + + sb.AppendLine(); + sb.AppendLine("[3] 이름 승격 — BossEvents.BossPhase(isSpawn, monsterId) 가 MonsterList 이름을 준다"); + sb.AppendLine(" 표 로드 여부: table_monsterlist.Ins=" + (table_monsterlist.Ins != null ? "있음" : "없음(에디트 모드)") + + " · table_localtext.Ins=" + (table_localtext.Ins != null ? "있음" : "없음")); + sb.AppendLine(" ResolveMonsterName(10006 Anubis)=" + (WL.UI.BossBanner.ResolveMonsterName(10006) ?? "(null · 표 미로드)")); + sb.AppendLine(" " + WL.UI.BossBanner.RaiseFakeBossPhaseSpawn(10006)); + sb.AppendLine(" → " + bc.Dump().Split('\n')[0].Trim()); + + sb.AppendLine(); + sb.AppendLine("[4] 직접 Trigger(이름 주입) — 표 없이도 이름 줄이 붙는지"); + sb.AppendLine(" " + bc.ResetDiagnostics() + " (에디트 모드는 Time 이 멈춰 가드가 안 풀린다)"); + sb.AppendLine(" " + bc.Trigger("아누비스", true)); + bc.Tick(Time.unscaledTime + 0.2f); + sb.AppendLine(); + sb.AppendLine("[5] 최종 덤프"); + sb.Append(bc.Dump()); + + sb.AppendLine(); + sb.AppendLine("[6] 813c 보스 HP 바와 같은 프레임 — 같은 Spawned Dispatch 를 함께 탄다"); + var barNode = hud.Find("WL_BossHpBar"); + var bar = barNode != null ? barNode.GetComponent() : null; + if (bar == null) sb.AppendLine(" 🔴 WL_BossHpBar 없음"); + else + { + bar.Initialize(); + bc.ResetDiagnostics(); + sb.AppendLine(" 구독자 Spawned=" + WL.Combat.Core.CombatEvents.Spawned.Count + " (배너 + 보스바)"); + int f0 = Time.frameCount; + sb.AppendLine(" " + WL.UI.BossHpBar.RaiseFakeBossSpawned(1000f)); + bc.Tick(Time.unscaledTime + 0.2f); // 페이드인 0.15s 뒤(t=0 은 α 0 이 정상) + sb.AppendLine(" 같은 프레임(frame=" + f0 + "): 배너 shows=" + bc.ShowCount + " visible=" + bc.Visible + + " · 보스바 visible=" + bar.Visible + " ratio=" + bar.LastRatio.ToString("F3")); + bar.Subscribe(false); + } + } + finally + { + if (bc != null) bc.Subscribe(false); + PrefabUtility.UnloadPrefabContents(root); + } + sb.AppendLine(); + sb.AppendLine("해제 후 구독자 Spawned=" + WL.Combat.Core.CombatEvents.Spawned.Count + + " BossPhase=" + WL.Combat.Boss.BossEvents.BossPhase.Count + " (0 이어야 한다)"); + var body = sb.ToString(); + Save("WL813tj_probe_boss.txt", body); + return body; + } + + // ═══ ⓑ 813j 물약 · 부활 · 피격 ══════════════════════════════════════════ + public static object DumpSurvival() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + WL.UI.HitVignette hv = null; + try + { + var hud = FindByPath(root.transform, HudPath); + var pad = FindByPath(root.transform, PadPath); + var s = WL.UI.WLSurvivalUiSettings.Instance; + if (s == null) return "🔴 WLSurvivalUiSettings 에셋 없음"; + + // ── A. 피격 테두리 + 가장자리 비네트 + var hvNode = hud != null ? hud.Find(WL813tj_ApplyNames.Hit) : null; + hv = hvNode != null ? hvNode.GetComponent() : null; + sb.AppendLine("[A] 피격 연출 (CombatEvents.Damaged · 실측 발생지 MyActor.cs:309 = PC 전용)"); + if (hv == null) sb.AppendLine(" 🔴 WL_HitVignette 없음"); + else + { + sb.AppendLine(" 구독 전 Damaged=" + WL.Combat.Core.CombatEvents.Damaged.Count); + sb.AppendLine(" " + hv.Initialize()); + sb.AppendLine(" 구독 후 Damaged=" + WL.Combat.Core.CombatEvents.Damaged.Count); + float t0 = Time.unscaledTime; + + sb.AppendLine(" ① 무적 피격(invincible=true · dmg 0) ×3 → 무시되어야 한다"); + for (int i = 0; i < 3; i++) WL.UI.HitVignette.RaiseFakeDamaged(0, true); + sb.AppendLine(" seen=" + hv.DamagedSeen + " 무적스킵=" + hv.InvincibleSkipped + " flashes=" + hv.FlashCount + + " borderα=" + hv.BorderAlpha.ToString("F3") + " (기대 flashes=0)"); + + sb.AppendLine(" ② 실피격(invincible=false · dmg 120) → 번쩍"); + sb.AppendLine(" " + WL.UI.HitVignette.RaiseFakeDamaged(120, false)); + sb.AppendLine(" t(s) | 테두리α | 가장자리α"); + foreach (var m in new[] { 0f, 0.10f, 0.20f, 0.29f, 0.31f }) + { + hv.Tick(t0 + m); + sb.AppendLine(" " + m.ToString("F2").PadLeft(5) + " | " + hv.BorderAlpha.ToString("F3").PadLeft(7) + + " | " + hv.EdgeAlpha.ToString("F3")); + } + sb.AppendLine(" ③ 같은 프레임 연타 → 스로틀(" + s.hitMinIntervalSeconds + "s)"); + int before = hv.FlashCount; + for (int i = 0; i < 4; i++) WL.UI.HitVignette.RaiseFakeDamaged(50, false); + sb.AppendLine(" 추가 요청 4 → flashes " + before + "→" + hv.FlashCount + " 스로틀스킵=" + hv.ThrottleSkipped); + sb.AppendLine(); + sb.Append(hv.Dump()); + hv.RemoveBorder(); // 프리팹에 굽지 않는다 — 검증 후 즉시 제거 + } + + // ── B. 부활 팝업 + sb.AppendLine(); + sb.AppendLine("[B] 부활 팝업 (공용 Popup/SortOrder_5 재사용 · 813i 미연결)"); + var rvNode = hud != null ? hud.Find(WL813tj_ApplyNames.Revive) : null; + var rv = rvNode != null ? rvNode.GetComponent() : null; + if (rv == null) sb.AppendLine(" 🔴 WL_ReviveDialog 없음"); + else + { + sb.AppendLine(" " + rv.Initialize()); + float t0 = Time.unscaledTime; + sb.AppendLine(" 813i 진입점 NotifyDeath() → " + WL.UI.ReviveDialog.NotifyDeath()); + rv.Tick(t0 + s.reviveDelaySeconds - 0.01f); + sb.AppendLine(" t=" + (s.reviveDelaySeconds - 0.01f).ToString("F2") + "s : 표시=" + rv.FallbackVisible + " 대기중=" + rv.Pending + " (기대 False/True)"); + rv.Tick(t0 + s.reviveDelaySeconds); + sb.AppendLine(" t=" + s.reviveDelaySeconds.ToString("F2") + "s : 표시=" + rv.FallbackVisible + + " 공용팝업사용=" + rv.UsedCommonPopup + " shows=" + rv.ShownCount); + sb.AppendLine(" 본문=\"" + rv.LastMessage.Replace("\n", " / ") + "\""); + bool got = false; + WL.UI.ReviveDialog.ReviveRequested = () => got = true; + sb.AppendLine(" 확인 → " + rv.OnConfirm() + " · 813i 콜백 수신=" + got + " · 표시=" + rv.FallbackVisible); + WL.UI.ReviveDialog.ReviveRequested = null; + sb.AppendLine(); + sb.Append(rv.Dump()); + } + + // ── C. 물약 버튼 + sb.AppendLine(); + sb.AppendLine("[C] 물약 버튼 (813c 예약 슬롯 · 813i Provider 미연결 → 대역으로 왕복 검증)"); + var ptNode = pad != null ? pad.Find(WL813tj_ApplyNames.Potion) : null; + var pt = ptNode != null ? ptNode.GetComponent() : null; + if (pt == null) sb.AppendLine(" 🔴 WL_PotionButton 없음"); + else + { + WL.UI.PotionButton.ClearProvider(); + sb.AppendLine(" " + pt.Initialize()); + sb.AppendLine(" ① 813i 미연결: HasProvider=" + WL.UI.PotionButton.HasProvider + " · " + pt.Refresh()); + sb.AppendLine(" 클릭 → " + pt.OnClickPotion() + " (used=" + pt.UsedCount + " blocked=" + pt.BlockedCount + ")"); + sb.AppendLine(" ② 813i 대역 설치: " + WL.UI.PotionButton.InstallFakeProvider(3, 5f)); + sb.AppendLine(" " + pt.Refresh()); + sb.AppendLine(" 클릭1 → " + pt.OnClickPotion() + " · " + pt.Refresh()); + sb.AppendLine(" 쿨 중 클릭2 → " + pt.OnClickPotion() + " · " + pt.Refresh()); + if (WL.UI.PotionButton.FakeCooldownSetter != null) WL.UI.PotionButton.FakeCooldownSetter(2.5f); + sb.AppendLine(" 쿨 절반(2.5/5) → " + pt.Refresh()); + if (WL.UI.PotionButton.FakeCooldownSetter != null) WL.UI.PotionButton.FakeCooldownSetter(0f); + sb.AppendLine(" 쿨 종료 → " + pt.Refresh()); + sb.AppendLine(" 클릭3 → " + pt.OnClickPotion()); + if (WL.UI.PotionButton.FakeCooldownSetter != null) WL.UI.PotionButton.FakeCooldownSetter(0f); + sb.AppendLine(" 클릭4 → " + pt.OnClickPotion() + " · " + pt.Refresh()); + if (WL.UI.PotionButton.FakeCooldownSetter != null) WL.UI.PotionButton.FakeCooldownSetter(0f); + sb.AppendLine(" 잔량 0 클릭5 → " + pt.OnClickPotion() + " · " + pt.Refresh()); + sb.AppendLine(); + sb.Append(pt.Dump()); + sb.AppendLine(" " + WL.UI.PotionButton.ClearProvider()); + } + } + finally + { + if (hv != null) hv.Subscribe(false); + PrefabUtility.UnloadPrefabContents(root); + } + sb.AppendLine(); + sb.AppendLine("해제 후 구독자 Damaged=" + WL.Combat.Core.CombatEvents.Damaged.Count + " (0 이어야 한다)"); + var body = sb.ToString(); + Save("WL813tj_probe_survival.txt", body); + return body; + } + + // ═══ 노드 배치 · 겹침 ═══════════════════════════════════════════════════ + public static object DumpPrefab() + { + var sb = new StringBuilder(); + var root = PrefabUtility.LoadPrefabContents(NewGameUIPath); + try + { + var hud = FindByPath(root.transform, HudPath); + var pad = FindByPath(root.transform, PadPath); + sb.AppendLine("[WL_HUD] children=" + (hud != null ? hud.childCount : -1) + + " SafeAreaFitter=" + (hud != null && hud.GetComponent() != null)); + if (hud != null) + for (int i = 0; i < hud.childCount; i++) + { + var c = hud.GetChild(i) as RectTransform; + sb.AppendLine(" [" + i + "] " + c.name + " pos" + c.anchoredPosition + " size" + c.sizeDelta + + " aMin" + c.anchorMin + " children=" + c.childCount + " comps=" + c.GetComponents().Length); + } + sb.AppendLine("[BattleUI] children=" + (pad != null ? pad.childCount : -1)); + if (pad != null) + for (int i = 0; i < pad.childCount; i++) + { + var c = pad.GetChild(i) as RectTransform; + sb.AppendLine(" [" + i + "] " + c.name + " pos" + c.anchoredPosition + " size" + c.sizeDelta + + " aMin" + c.anchorMin + " active=" + c.gameObject.activeSelf); + } + + // 배너 · 보스바 세로 겹침 검사(px) + var hudS = WL.UI.WLHudLayoutSettings.Instance; + var bs = WL.UI.WLBossUiSettings.Instance; + if (hudS != null && bs != null) + { + float barTop = hudS.bossBarTopMarginPx; + float barBottom = barTop + hudS.bossBarSizePx.y + hudS.bossBarNameFontPx + hudS.bossBarNameGapPx; + float banTop = bs.bannerTopMarginPx, banBottom = banTop + bs.bannerSizePx.y; + sb.AppendLine(); + sb.AppendLine("[겹침 · 상단에서 px] 보스바 " + barTop.ToString("F0") + "~" + barBottom.ToString("F0") + + " · 배너 " + banTop.ToString("F0") + "~" + banBottom.ToString("F0") + + " → 겹침=" + (banTop < barBottom)); + sb.AppendLine(" 813g 연쇄문구 = 화면 중앙 위 " + (WL.UI.WLCombatTextSettings.Instance != null ? + WL.UI.WLCombatTextSettings.Instance.killChainTopOffsetPx.ToString("F0") : "?") + " px (중앙 기준 · 상단 밴드와 별개)"); + } + + // 물약 버튼과 813c 슬롯 간 최소 여백 + if (hudS != null) + { + var sur = WL.UI.WLSurvivalUiSettings.Instance; + int idx = sur != null ? sur.potionReserveSlotIndex : 0; + Vector2 pp = hudS.ReserveSlotPx(idx); + float pr = hudS.reserveDiameterPx * 0.5f; + float min = float.MaxValue; string who = ""; + for (int i = 0; i < hudS.activeSkillSlots; i++) + { + var q = hudS.FanSlotPx(i); + float g = Vector2.Distance(pp, q) - pr - hudS.slotDiameterPx * 0.5f; + if (g < min) { min = g; who = "slot" + i; } + } + float ga = Vector2.Distance(pp, hudS.attackCenterPx) - pr - hudS.attackDiameterPx * 0.5f; + if (ga < min) { min = ga; who = "Attack"; } + sb.AppendLine(); + sb.AppendLine("[물약 버튼] 예약 슬롯" + idx + " dx/dy px=" + pp + " 지름=" + hudS.reserveDiameterPx + + "px · 최소 여백=" + min.ToString("F1") + "px (" + who + ") · 기준 ≥16 → " + (min >= 16f ? "OK" : "🔴")); + sb.AppendLine(" 모서리 도달 반경 = " + (pp.magnitude + pr).ToString("F1") + "px (기준서 목표 " + hudS.thumbReachRadiusPx + "px)"); + } + } + finally { PrefabUtility.UnloadPrefabContents(root); } + var body = sb.ToString(); + Save("WL813tj_probe_prefab.txt", body); + return body; + } +} + +/// Apply 스크립트와 이름을 맞추기 위한 상수(run_script 는 파일마다 독립 어셈블리라 참조가 안 된다 · 813c 교훈). +public static class WL813tj_ApplyNames +{ + public const string Banner = "WL_BossBanner"; + public const string Hit = "WL_HitVignette"; + public const string Revive = "WL_ReviveDialog"; + public const string Potion = "WL_PotionButton"; +} diff --git a/Assets/Res_Addr/MainUI/NewGameUI.prefab b/Assets/Res_Addr/MainUI/NewGameUI.prefab index 2189f76d1..46ba61f3b 100644 --- a/Assets/Res_Addr/MainUI/NewGameUI.prefab +++ b/Assets/Res_Addr/MainUI/NewGameUI.prefab @@ -5897,6 +5897,81 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &373395512599707266 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3325875189365581052} + - component: {fileID: 8988475761999303918} + - component: {fileID: 3717000762044804789} + m_Layer: 5 + m_Name: Right + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3325875189365581052 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 373395512599707266} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: -1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 805690767876694728} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 0} + m_Pivot: {x: 1, y: 0.5} +--- !u!222 &8988475761999303918 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 373395512599707266} + m_CullTransparentMesh: 1 +--- !u!114 &3717000762044804789 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 373395512599707266} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &376846047770435162 GameObject: m_ObjectHideFlags: 0 @@ -7780,6 +7855,59 @@ MonoBehaviour: textMeshPro: {fileID: 571931102548782567} icon: {fileID: 4529481489266646413} RightOffset: 0.25 +--- !u!1 &532829661294736831 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 513814516531735066} + - component: {fileID: 4249795429928467136} + m_Layer: 5 + m_Name: WL_SafeArea_Front + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &513814516531735066 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 532829661294736831} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4985824089725729178} + - {fileID: 6291925347982253742} + - {fileID: 4768237605214567188} + m_Father: {fileID: 5707331028172779298} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4249795429928467136 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 532829661294736831} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f4cdcc41055ee140ae3a9916e8563ce, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.SafeAreaFitter + applyHorizontal: 1 + applyVertical: 1 --- !u!1 &542249507365626154 GameObject: m_ObjectHideFlags: 0 @@ -8030,7 +8158,7 @@ RectTransform: - {fileID: 2975530085048663680} - {fileID: 2738232944486714762} - {fileID: 8382031498026770910} - m_Father: {fileID: 5707331028172779298} + m_Father: {fileID: 513814516531735066} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -10310,6 +10438,127 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &729993010250605578 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1588856824279851085} + - component: {fileID: 1378419845745059537} + - component: {fileID: 1729832211458897918} + - component: {fileID: 3440298961649701797} + m_Layer: 5 + m_Name: btn_ok + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1588856824279851085 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 729993010250605578} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3359660681806388314} + m_Father: {fileID: 6057289453489918498} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 49.77778} + m_SizeDelta: {x: 568.8889, y: 170.66667} + m_Pivot: {x: 0.5, y: 0} +--- !u!222 &1378419845745059537 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 729993010250605578} + m_CullTransparentMesh: 1 +--- !u!114 &1729832211458897918 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 729993010250605578} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0.137, g: 0.906, b: 0.529, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &3440298961649701797 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 729993010250605578} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1729832211458897918} + m_OnClick: + m_PersistentCalls: + m_Calls: [] --- !u!1 &736185933554103205 GameObject: m_ObjectHideFlags: 0 @@ -12240,6 +12489,58 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &828786773394226853 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8642140347996550916} + - component: {fileID: 5577355867568910787} + m_Layer: 5 + m_Name: WL_SafeArea_Back + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8642140347996550916 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828786773394226853} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8541309915134075684} + - {fileID: 2931286266799411332} + m_Father: {fileID: 5707331028172779298} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5577355867568910787 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 828786773394226853} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f4cdcc41055ee140ae3a9916e8563ce, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.SafeAreaFitter + applyHorizontal: 1 + applyVertical: 1 --- !u!1 &830521825607074813 GameObject: m_ObjectHideFlags: 0 @@ -15883,6 +16184,144 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1052164011154499965 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3359660681806388314} + - component: {fileID: 6801274782102350417} + - component: {fileID: 9118361487345624753} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3359660681806388314 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052164011154499965} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1588856824279851085} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6801274782102350417 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052164011154499965} + m_CullTransparentMesh: 1 +--- !u!114 &9118361487345624753 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052164011154499965} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uBD80\uD65C" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.04, g: 0.09, b: 0.06, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 62.577778 + m_fontSizeBase: 62.577778 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &1057926875779325409 GameObject: m_ObjectHideFlags: 0 @@ -16961,7 +17400,7 @@ RectTransform: - {fileID: 365265949171303323} - {fileID: 4247629930335866296} - {fileID: 9189970466948064939} - m_Father: {fileID: 5707331028172779298} + m_Father: {fileID: 8642140347996550916} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -20279,6 +20718,81 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1261177297126528488 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2346494613726305633} + - component: {fileID: 3117432890429355239} + - component: {fileID: 5654830210870845350} + m_Layer: 5 + m_Name: Dim + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2346494613726305633 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261177297126528488} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7397473078670142153} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3117432890429355239 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261177297126528488} + m_CullTransparentMesh: 1 +--- !u!114 &5654830210870845350 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261177297126528488} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0.6} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &1274874128976412434 GameObject: m_ObjectHideFlags: 0 @@ -28049,6 +28563,45 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ab4e7dba3733e584abb76cd4fbc0e116, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!1 &1727488926143090982 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1665835260916353456} + m_Layer: 5 + m_Name: Edge + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1665835260916353456 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1727488926143090982} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6516827735383330427} + - {fileID: 7557697127358840222} + - {fileID: 3230640079981627107} + - {fileID: 1814651213277551832} + m_Father: {fileID: 5897938616589152734} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &1735093912695322795 GameObject: m_ObjectHideFlags: 0 @@ -42054,6 +42607,45 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_localtextKey: 429 +--- !u!1 &2531023993604290304 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 805690767876694728} + m_Layer: 5 + m_Name: Warn + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &805690767876694728 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2531023993604290304} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8112293384407471970} + - {fileID: 3325875189365581052} + - {fileID: 2645861652412744642} + - {fileID: 6621108134402918282} + m_Father: {fileID: 1393002576826920595} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &2537257571206545845 GameObject: m_ObjectHideFlags: 0 @@ -50025,6 +50617,44 @@ MonoBehaviour: - {fileID: 5714530668851046310} - {fileID: 4530122692014752591} m_BanListUI: {fileID: 2253473854110573972} +--- !u!1 &3046588334393759983 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2740441617943509984} + m_Layer: 5 + m_Name: Banner + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2740441617943509984 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3046588334393759983} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8669492132903119608} + - {fileID: 164292194477288044} + - {fileID: 1919755678270827166} + m_Father: {fileID: 1393002576826920595} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 1} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: -533.3333} + m_SizeDelta: {x: 1528.8889, y: 266.66666} + m_Pivot: {x: 0.5, y: 1} --- !u!1 &3047559588408359077 GameObject: m_ObjectHideFlags: 0 @@ -58182,6 +58812,81 @@ MonoBehaviour: m_OnValueChanged: m_PersistentCalls: m_Calls: [] +--- !u!1 &3539353401262932030 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8112293384407471970} + - component: {fileID: 8142412729431859181} + - component: {fileID: 7320693879829000026} + m_Layer: 5 + m_Name: Left + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8112293384407471970 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3539353401262932030} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 805690767876694728} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 0} + m_Pivot: {x: 0, y: 0.5} +--- !u!222 &8142412729431859181 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3539353401262932030} + m_CullTransparentMesh: 1 +--- !u!114 &7320693879829000026 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3539353401262932030} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &3543312459991925934 GameObject: m_ObjectHideFlags: 0 @@ -59634,6 +60339,81 @@ MonoBehaviour: TextCol_off: {r: 1, g: 1, b: 1, a: 1} texts: - {fileID: 7311846923921173660} +--- !u!1 &3649249583604328219 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8137271292383277095} + - component: {fileID: 47175734825936804} + - component: {fileID: 3426905527962841525} + m_Layer: 5 + m_Name: Ring + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8137271292383277095 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3649249583604328219} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6509309801110796452} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &47175734825936804 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3649249583604328219} + m_CullTransparentMesh: 1 +--- !u!114 &3426905527962841525 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3649249583604328219} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0.65} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 3 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 0 + m_FillClockwise: 1 + m_FillOrigin: 2 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &3676624380405786312 GameObject: m_ObjectHideFlags: 0 @@ -59811,6 +60591,81 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &3682722181464489969 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1814651213277551832} + - component: {fileID: 1158633003044627607} + - component: {fileID: 3835109656621765770} + m_Layer: 5 + m_Name: Top + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1814651213277551832 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3682722181464489969} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: -1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1665835260916353456} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 248.88889} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &1158633003044627607 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3682722181464489969} + m_CullTransparentMesh: 1 +--- !u!114 &3835109656621765770 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3682722181464489969} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &3706951122825007051 GameObject: m_ObjectHideFlags: 0 @@ -80013,6 +80868,76 @@ RectTransform: m_AnchoredPosition: {x: 122.5, y: -10} m_SizeDelta: {x: 40, y: 40} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &5071874048594515121 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1393002576826920595} + - component: {fileID: 4872815827339634419} + - component: {fileID: 5231351298950991292} + m_Layer: 5 + m_Name: WL_BossBanner + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1393002576826920595 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5071874048594515121} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 805690767876694728} + - {fileID: 2740441617943509984} + m_Father: {fileID: 6746702601929578265} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4872815827339634419 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5071874048594515121} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: be56aa9524b103044b91f08a879a1502, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.BossBanner + group: {fileID: 5231351298950991292} + bannerBox: {fileID: 2740441617943509984} + bannerBg: {fileID: 5406559764303854279} + titleLabel: {fileID: 7473028900813323745} + nameLabel: {fileID: 4762789479093148363} + warnRoot: {fileID: 805690767876694728} + font: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} +--- !u!225 &5231351298950991292 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5071874048594515121} + m_Enabled: 1 + m_Alpha: 0 + m_Interactable: 0 + m_BlocksRaycasts: 0 + m_IgnoreParentGroups: 0 --- !u!1 &5073903825952328520 GameObject: m_ObjectHideFlags: 0 @@ -82969,6 +83894,81 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5317243625885448932 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3230640079981627107} + - component: {fileID: 2306036620514555240} + - component: {fileID: 2651114101219932830} + m_Layer: 5 + m_Name: Bottom + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3230640079981627107 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5317243625885448932} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1665835260916353456} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 248.88889} + m_Pivot: {x: 0.5, y: 0} +--- !u!222 &2306036620514555240 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5317243625885448932} + m_CullTransparentMesh: 1 +--- !u!114 &2651114101219932830 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5317243625885448932} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &5318086363929733485 GameObject: m_ObjectHideFlags: 0 @@ -87908,7 +88908,7 @@ RectTransform: - {fileID: 6924126925575544377} - {fileID: 7568023033280500970} - {fileID: 1950309627796175630} - m_Father: {fileID: 5707331028172779298} + m_Father: {fileID: 513814516531735066} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -97177,6 +98177,81 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &6352879672638466917 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6516827735383330427} + - component: {fileID: 2513743546033175061} + - component: {fileID: 1510955350853969169} + m_Layer: 5 + m_Name: Left + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6516827735383330427 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6352879672638466917} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1665835260916353456} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 248.88889, y: 0} + m_Pivot: {x: 0, y: 0.5} +--- !u!222 &2513743546033175061 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6352879672638466917} + m_CullTransparentMesh: 1 +--- !u!114 &1510955350853969169 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6352879672638466917} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &6357254734735818847 GameObject: m_ObjectHideFlags: 0 @@ -98262,6 +99337,144 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6413898004924447116 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1919755678270827166} + - component: {fileID: 8530771226282976162} + - component: {fileID: 4762789479093148363} + m_Layer: 5 + m_Name: Name + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1919755678270827166 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6413898004924447116} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2740441617943509984} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -170.66667} + m_SizeDelta: {x: 0, y: 99.55556} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8530771226282976162 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6413898004924447116} + m_CullTransparentMesh: 1 +--- !u!114 &4762789479093148363 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6413898004924447116} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 0.941, b: 0.722, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 99.55556 + m_fontSizeBase: 99.55556 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &6427640950740531084 GameObject: m_ObjectHideFlags: 0 @@ -99935,6 +101148,81 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &6545820991182283479 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8669492132903119608} + - component: {fileID: 1576579349420116833} + - component: {fileID: 5406559764303854279} + m_Layer: 5 + m_Name: Bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8669492132903119608 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6545820991182283479} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2740441617943509984} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1576579349420116833 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6545820991182283479} + m_CullTransparentMesh: 1 +--- !u!114 &5406559764303854279 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6545820991182283479} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0.55} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &6554038464462392755 GameObject: m_ObjectHideFlags: 0 @@ -107001,6 +108289,144 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: -20, y: -20} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &6975741310607593924 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5944300935449898149} + - component: {fileID: 5306665608407477760} + - component: {fileID: 7135513457681813806} + m_Layer: 5 + m_Name: Count + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5944300935449898149 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6975741310607593924} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6509309801110796452} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -3.5555556, y: -3.5555556} + m_SizeDelta: {x: -7.111111, y: -7.111111} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5306665608407477760 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6975741310607593924} + m_CullTransparentMesh: 1 +--- !u!114 &7135513457681813806 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6975741310607593924} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 3 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.137, g: 0.906, b: 0.529, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 60.444447 + m_fontSizeBase: 60.444447 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 4 + m_VerticalAlignment: 1024 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &6978939766476860517 GameObject: m_ObjectHideFlags: 0 @@ -109870,6 +111296,9 @@ RectTransform: - {fileID: 3852854134505927621} - {fileID: 2659634104557254342} - {fileID: 2892688380935435354} + - {fileID: 1393002576826920595} + - {fileID: 5897938616589152734} + - {fileID: 7397473078670142153} m_Father: {fileID: 2647977513349308266} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -113541,6 +114970,77 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &7453136843902692446 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7397473078670142153} + - component: {fileID: 4628206839012537628} + - component: {fileID: 7220338137780933989} + m_Layer: 5 + m_Name: WL_ReviveDialog + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7397473078670142153 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7453136843902692446} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2346494613726305633} + - {fileID: 6057289453489918498} + m_Father: {fileID: 6746702601929578265} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4628206839012537628 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7453136843902692446} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ca217128e8345cd4e830282582e29a9c, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.ReviveDialog + group: {fileID: 7220338137780933989} + box: {fileID: 6057289453489918498} + dim: {fileID: 5654830210870845350} + boxBg: {fileID: 1936739007659065633} + messageLabel: {fileID: 8783128708711054796} + okButton: {fileID: 3440298961649701797} + okLabel: {fileID: 9118361487345624753} + font: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} +--- !u!225 &7220338137780933989 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7453136843902692446} + m_Enabled: 1 + m_Alpha: 0 + m_Interactable: 0 + m_BlocksRaycasts: 0 + m_IgnoreParentGroups: 0 --- !u!1 &7456735301317926964 GameObject: m_ObjectHideFlags: 0 @@ -113907,6 +115407,144 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &7473372183818717751 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5574642658095754037} + - component: {fileID: 7524707505705108435} + - component: {fileID: 8783128708711054796} + m_Layer: 5 + m_Name: Msg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5574642658095754037 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7473372183818717751} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6057289453489918498} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.35} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -21.333336} + m_SizeDelta: {x: -85.33334, y: -42.66667} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7524707505705108435 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7473372183818717751} + m_CullTransparentMesh: 1 +--- !u!114 &8783128708711054796 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7473372183818717751} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 78.22222 + m_fontSizeBase: 78.22222 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &7475715783848836104 GameObject: m_ObjectHideFlags: 0 @@ -115823,7 +117461,7 @@ RectTransform: - {fileID: 795777954291663711} - {fileID: 6415367922768528216} - {fileID: 3948127612777823680} - m_Father: {fileID: 5707331028172779298} + m_Father: {fileID: 8642140347996550916} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -116042,6 +117680,81 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &7608721062071740427 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7557697127358840222} + - component: {fileID: 7038998733017637315} + - component: {fileID: 6179810493362378125} + m_Layer: 5 + m_Name: Right + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7557697127358840222 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7608721062071740427} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: -1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1665835260916353456} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 248.88889, y: 0} + m_Pivot: {x: 1, y: 0.5} +--- !u!222 &7038998733017637315 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7608721062071740427} + m_CullTransparentMesh: 1 +--- !u!114 &6179810493362378125 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7608721062071740427} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &7619617252624222251 GameObject: m_ObjectHideFlags: 0 @@ -119196,6 +120909,56 @@ MonoBehaviour: m_ScrollRect: {fileID: 6288159255424441122} m_Content: {fileID: 0} go_card: {fileID: 4796869527734321784, guid: f8576242c9a6a8847894da069bf85bba, type: 3} +--- !u!1 &7802305355192172600 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5897938616589152734} + - component: {fileID: 148676473597931085} + m_Layer: 5 + m_Name: WL_HitVignette + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5897938616589152734 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7802305355192172600} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1665835260916353456} + m_Father: {fileID: 6746702601929578265} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &148676473597931085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7802305355192172600} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 863efecd89e890e448a36adf35578b68, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.HitVignette + vignetteRoot: {fileID: 1665835260916353456} --- !u!1 &7802634216131593600 GameObject: m_ObjectHideFlags: 0 @@ -119414,6 +121177,81 @@ MonoBehaviour: m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 m_ReverseArrangement: 0 +--- !u!1 &7826904674949617537 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6621108134402918282} + - component: {fileID: 4075731166244058153} + - component: {fileID: 571745315991903605} + m_Layer: 5 + m_Name: Top + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6621108134402918282 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7826904674949617537} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: -1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 805690767876694728} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 320} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &4075731166244058153 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7826904674949617537} + m_CullTransparentMesh: 1 +--- !u!114 &571745315991903605 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7826904674949617537} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &7835144401862305810 GameObject: m_ObjectHideFlags: 0 @@ -119961,6 +121799,144 @@ MonoBehaviour: m_OnValueChanged: m_PersistentCalls: m_Calls: [] +--- !u!1 &7874375426055098609 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 846904675603174916} + - component: {fileID: 7878209128017314805} + - component: {fileID: 1153402386953601198} + m_Layer: 5 + m_Name: Icon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &846904675603174916 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7874375426055098609} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6509309801110796452} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7878209128017314805 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7874375426055098609} + m_CullTransparentMesh: 1 +--- !u!114 &1153402386953601198 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7874375426055098609} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\uBB3C\uC57D" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.137, g: 0.906, b: 0.529, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 53.333332 + m_fontSizeBase: 53.333332 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &7876878074327797899 GameObject: m_ObjectHideFlags: 0 @@ -124302,6 +126278,83 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8155396461287654673 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6057289453489918498} + - component: {fileID: 6881721039995314687} + - component: {fileID: 1936739007659065633} + m_Layer: 5 + m_Name: Box + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6057289453489918498 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8155396461287654673} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5574642658095754037} + - {fileID: 1588856824279851085} + m_Father: {fileID: 7397473078670142153} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 1351.1111, y: 675.55554} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6881721039995314687 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8155396461287654673} + m_CullTransparentMesh: 1 +--- !u!114 &1936739007659065633 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8155396461287654673} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0.06, g: 0.07, b: 0.09, a: 0.92} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &8162699013497819267 GameObject: m_ObjectHideFlags: 0 @@ -128028,6 +130081,81 @@ MonoBehaviour: TextCol_off: {r: 1, g: 1, b: 1, a: 1} texts: - {fileID: 3799973230255533897} +--- !u!1 &8393517844422812743 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2645861652412744642} + - component: {fileID: 2743357965233725009} + - component: {fileID: 5384932537964706010} + m_Layer: 5 + m_Name: Bottom + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2645861652412744642 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8393517844422812743} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 805690767876694728} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 320} + m_Pivot: {x: 0.5, y: 0} +--- !u!222 &2743357965233725009 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8393517844422812743} + m_CullTransparentMesh: 1 +--- !u!114 &5384932537964706010 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8393517844422812743} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &8395830976454375402 GameObject: m_ObjectHideFlags: 0 @@ -128918,7 +131046,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 583420463614348644} - m_Father: {fileID: 5707331028172779298} + m_Father: {fileID: 513814516531735066} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -132160,6 +134288,162 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8706014859878399905 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6509309801110796452} + - component: {fileID: 5465276067866271373} + - component: {fileID: 6307484648309462483} + - component: {fileID: 1125108165217873954} + - component: {fileID: 6581817982974349217} + - component: {fileID: 392479859577101366} + m_Layer: 5 + m_Name: WL_PotionButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6509309801110796452 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8137271292383277095} + - {fileID: 846904675603174916} + - {fileID: 5944300935449898149} + m_Father: {fileID: 4825512513270908954} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: -435.02774, y: 665.079} + m_SizeDelta: {x: 195.55556, y: 195.55556} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5465276067866271373 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 64e4b2b6baa015840acbc47f37476e13, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::WL.UI.PotionButton + background: {fileID: 6581817982974349217} + cooldownRing: {fileID: 3426905527962841525} + iconLabel: {fileID: 1153402386953601198} + countLabel: {fileID: 7135513457681813806} + button: {fileID: 392479859577101366} + group: {fileID: 6307484648309462483} + font: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} +--- !u!225 &6307484648309462483 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_Enabled: 1 + m_Alpha: 1 + m_Interactable: 1 + m_BlocksRaycasts: 1 + m_IgnoreParentGroups: 0 +--- !u!222 &1125108165217873954 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_CullTransparentMesh: 1 +--- !u!114 &6581817982974349217 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0.129, g: 0.145, b: 0.176, a: 0.85} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &392479859577101366 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8706014859878399905} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6581817982974349217} + m_OnClick: + m_PersistentCalls: + m_Calls: [] --- !u!1 &8706117098357048695 GameObject: m_ObjectHideFlags: 0 @@ -133788,13 +136072,10 @@ RectTransform: - {fileID: 8144537169185330793} - {fileID: 7862232602542509387} - {fileID: 8460797171243959167} - - {fileID: 8541309915134075684} - - {fileID: 2931286266799411332} + - {fileID: 8642140347996550916} - {fileID: 2647977513349308266} - {fileID: 4693863785291490405} - - {fileID: 4985824089725729178} - - {fileID: 6291925347982253742} - - {fileID: 4768237605214567188} + - {fileID: 513814516531735066} - {fileID: 5140710283611032768} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -136677,6 +138958,144 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_ShowMaskGraphic: 0 +--- !u!1 &8946807470326497562 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 164292194477288044} + - component: {fileID: 6098183332153660785} + - component: {fileID: 7473028900813323745} + m_Layer: 5 + m_Name: Title + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &164292194477288044 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8946807470326497562} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2740441617943509984} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 170.66667} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &6098183332153660785 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8946807470326497562} + m_CullTransparentMesh: 1 +--- !u!114 &7473028900813323745 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8946807470326497562} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: BOSS + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a387e325271126742ad15569dba1ac57, type: 2} + m_sharedMaterial: {fileID: -6459762427321423278, guid: a387e325271126742ad15569dba1ac57, + type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 0.271, b: 0.278, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 170.66667 + m_fontSizeBase: 170.66667 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 00000000 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} --- !u!1 &8958513642575816722 GameObject: m_ObjectHideFlags: 0 @@ -170532,7 +172951,11 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] - m_AddedGameObjects: [] + m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 4460242486586314136, guid: c327e063c90438e419668019b3490455, + type: 3} + insertIndex: -1 + addedObject: {fileID: 6509309801110796452} m_AddedComponents: - targetCorrespondingSourceObject: {fileID: 4055677999475420392, guid: c327e063c90438e419668019b3490455, type: 3} diff --git a/Assets/WL/UI/Scripts/BossBanner.cs b/Assets/WL/UI/Scripts/BossBanner.cs new file mode 100644 index 000000000..8f83f6048 --- /dev/null +++ b/Assets/WL/UI/Scripts/BossBanner.cs @@ -0,0 +1,447 @@ +// ───────────────────────────────────────────────────────────────────────────── +// BossBanner.cs — 보스 등장 배너 + 경고 비네트 (WL-813tj · 813t · #813) +// +// 기준서 v1 §D-1 813t 행 / §B 요소 6 "등장 · 처치 연출": +// Spawned(isBoss) → 상단 "BOSS" 배너 1.2 s + 화면 가장자리 붉은 UI 비네트 0.8 s +// (포스트 프로세싱 금지 → UI 이미지) · 보스 이름 = MonsterList.n_MonsterName · 811d 오빗과 동시. +// +// ■ 이벤트 (구독만 · 발행 0) +// ① WL.Combat.Core.CombatEvents.Spawned(isBoss) — 813c 보스 HP 바와 **같은 디스패치**를 탄다 +// → 같은 프레임에 배너와 바가 함께 뜬다(구독 순서와 무관 · 같은 Dispatch 안). +// ② WL.Combat.Boss.BossEvents.BossPhase(isSpawn) — 813h 가 내는 페이즈 1 진입. +// 이쪽만 **monsterId** 를 준다 → 이름은 여기서 나온다. 먼저 온 쪽이 배너를 열고, +// 뒤늦게 이름이 오면 표시 중인 배너의 이름 줄만 갱신한다(중복 표시 없음). +// 이벤트가 없으면 아무 것도 뜨지 않는다 — 폴링 폴백을 두지 않는다(813c 규칙). +// +// ■ 값 = WLBossUiSettings.asset (C45) · px→유닛 = 813c WLHudLayoutSettings.UnitsPerPx 하나만. +// ■ 숨김 = CanvasGroup alpha (GameObject 를 끄면 OnEnable 이 안 돌아 구독이 끊긴다 · 813c 규칙) +// ■ 시간 = Time.unscaledTime (811b 히트스톱·킬캠 슬로모 중에도 배너 길이가 흔들리지 않게) +// +// 🔴 어셈블리 주의: Assets/WL/UI/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일). +// ───────────────────────────────────────────────────────────────────────────── + +using System.Text; +using TMPro; +using UnityEngine; +using UnityEngine.UI; +using WL.Combat.Boss; +using WL.Combat.Core; + +namespace WL.UI +{ + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class BossBanner : MonoBehaviour + { + [Header("구성 요소 (BuildIfNeeded 가 만든다)")] + [SerializeField] private CanvasGroup group; + [SerializeField] private RectTransform bannerBox; + [SerializeField] private Image bannerBg; + [SerializeField] private TextMeshProUGUI titleLabel; + [SerializeField] private TextMeshProUGUI nameLabel; + [SerializeField] private RectTransform warnRoot; + + [Header("폰트 (에디터가 주입)")] + [SerializeField] private TMP_FontAsset font; + + private RectTransform _rt; + private Canvas _canvas; + private WLEdgeVignette _warn; + private bool _subscribed; + + private float _bannerStart = -1f; // 배너 시작 unscaledTime (-1 = 꺼짐) + private float _warnStart = -1f; + private float _lastTrigger = -999f; + private string _shownName = ""; + private bool _nameKnown; + + // ── 진단(프로브가 읽는다) ──────────────────────────────────────────── + public int SpawnedSeen { get; private set; } + public int BossSpawnSeen { get; private set; } + public int PhaseSeen { get; private set; } + public int ShowCount { get; private set; } + public string LastName { get { return _shownName; } } + public bool Visible { get { return group != null && group.alpha > 0.001f; } } + public float BannerAlpha { get { return group != null ? group.alpha : 0f; } } + public float WarnAlpha { get { return _warn != null ? _warn.CurrentAlpha : 0f; } } + public float BannerScale { get { return bannerBox != null ? bannerBox.localScale.x : 0f; } } + + private void Awake() { _rt = GetComponent(); } + private void OnEnable() { Initialize(); } + private void OnDisable() { Subscribe(false); } + + /// OnEnable 본체 — 에디트 모드 검증이 런타임과 같은 경로를 타도록 분리했다(813c 교훈). + public string Initialize() + { + if (_rt == null) _rt = GetComponent(); + BuildIfNeeded(); + string layout = ApplyLayout(); + HideNow(); + var s = WLBossUiSettings.Instance; + Subscribe(s == null || s.bannerEnabled); + return "initialized subscribed=" + _subscribed + " · " + layout; + } + + public void Subscribe(bool on) + { + if (on == _subscribed) return; + _subscribed = on; + if (on) + { + CombatEvents.Spawned.Add(OnSpawned); + BossEvents.BossPhase.Add(OnBossPhase); + } + else + { + CombatEvents.Spawned.Remove(OnSpawned); + BossEvents.BossPhase.Remove(OnBossPhase); + } + } + + // ── 구독 ────────────────────────────────────────────────────────────── + private void OnSpawned(in SpawnedEvent e) + { + SpawnedSeen++; + if (!e.isBoss) return; + BossSpawnSeen++; + string n = e.actor != null ? e.actor.name : null; + Trigger(n, false); + } + + private void OnBossPhase(in BossPhaseEvent e) + { + PhaseSeen++; + if (!e.isSpawn) return; + string n = ResolveMonsterName(e.monsterId); + Trigger(n, !string.IsNullOrEmpty(n)); + } + + /// MonsterList.n_MonsterName → localtext. 표가 없으면(에디트 모드) null. + public static string ResolveMonsterName(int monsterId) + { + if (monsterId <= 0) return null; + try + { + if (table_monsterlist.Ins == null) return null; + var d = table_monsterlist.Ins.Get_Data_orNull(monsterId); + if (d == null) return null; + if (table_localtext.Ins == null) return null; + return d.Get_Name(); + } + catch { return null; } // 표 미로드 상태에서 연출이 전투를 끊지 않게 + } + + /// + /// 배너를 연다. 이미 표시 중이면 이름만 승격한다(같은 스폰에서 Spawned·BossPhase 가 둘 다 오는 경우). + /// + public string Trigger(string bossName, bool nameIsAuthoritative) + { + var s = WLBossUiSettings.Instance; + if (s == null) return "WLBossUiSettings 에셋 없음 — 표시 안 함"; + if (!s.bannerEnabled) return "bannerEnabled=false — 표시 안 함"; + + float now = Time.unscaledTime; + bool showing = _bannerStart >= 0f && now - _bannerStart < s.bannerSeconds; + + if (showing || now - _lastTrigger < s.retriggerGuardSeconds) + { + // 중복 트리거 — 더 정확한 이름이 왔을 때만 갱신한다. + if (nameIsAuthoritative && !string.IsNullOrEmpty(bossName)) SetName(bossName, true, s); + return "재트리거 억제(guard " + s.retriggerGuardSeconds.ToString("F1") + "s) name=" + _shownName; + } + + _lastTrigger = now; + _bannerStart = now; + _warnStart = s.warnVignetteEnabled ? now : -1f; + ShowCount++; + SetName(bossName, nameIsAuthoritative, s); + ApplyLayout(); + Tick(now); + + if (s.verboseLog) Debug.Log("[BossBanner] show name=" + _shownName + " banner=" + s.bannerSeconds + "s warn=" + s.warnVignetteSeconds + "s"); + return "shown name=" + (string.IsNullOrEmpty(_shownName) ? "(없음)" : _shownName) + + " banner=" + s.bannerSeconds.ToString("F2") + "s warn=" + (_warnStart >= 0f ? s.warnVignetteSeconds.ToString("F2") + "s" : "off"); + } + + private void SetName(string bossName, bool authoritative, WLBossUiSettings s) + { + if (authoritative || !_nameKnown) + { + _shownName = bossName ?? ""; + _nameKnown = authoritative; + } + if (titleLabel != null) titleLabel.text = s.bannerTitleText; + if (nameLabel != null) + { + nameLabel.text = _shownName; + bool show = !(s.hideNameWhenUnknown && string.IsNullOrEmpty(_shownName)); + if (nameLabel.gameObject.activeSelf != show) nameLabel.gameObject.SetActive(show); + } + } + + private void Update() { Tick(Time.unscaledTime); } + + /// 배너·비네트 진행. 에디트 모드 프로브가 시간을 넣어 같은 경로로 검증한다. + public void Tick(float now) + { + var s = WLBossUiSettings.Instance; + if (s == null) return; + + // ── 배너 + if (_bannerStart >= 0f) + { + float t = now - _bannerStart; + if (t >= s.bannerSeconds) { _bannerStart = -1f; SetBannerAlpha(0f); } + else + { + float a = 1f; + if (s.bannerFadeInSeconds > 0f && t < s.bannerFadeInSeconds) a = t / s.bannerFadeInSeconds; + float outStart = s.bannerSeconds - s.bannerFadeOutSeconds; + if (s.bannerFadeOutSeconds > 0f && t > outStart) a = Mathf.Min(a, (s.bannerSeconds - t) / s.bannerFadeOutSeconds); + SetBannerAlpha(Mathf.Clamp01(a)); + + // 등장 펀치 → 원래 크기로 수렴(813g 텍스트 연출과 같은 계열) + if (bannerBox != null) + { + float k = (s.bannerPunchSeconds > 0f) ? Mathf.Clamp01(t / s.bannerPunchSeconds) : 1f; + float sc = Mathf.Lerp(s.bannerPunchScale, 1f, k); + bannerBox.localScale = new Vector3(sc, sc, 1f); + } + } + } + + // ── 경고 비네트 + if (_warnStart >= 0f && _warn != null && _warn.IsBuilt) + { + float t = now - _warnStart; + if (t >= s.warnVignetteSeconds) { _warnStart = -1f; _warn.SetAlpha(s.warnVignetteColor, 0f); } + else + { + _warn.SetAlpha(s.warnVignetteColor, PulseCurve(t, s.warnVignetteSeconds, s.warnVignetteFadeInSeconds, s.warnVignettePulses)); + } + } + } + + /// 0→1→0 맥동. pulses 회 반복하고, 첫 상승만 fadeIn 시간을 따른다. + public static float PulseCurve(float t, float total, float fadeIn, int pulses) + { + if (total <= 0f) return 0f; + int n = Mathf.Max(1, pulses); + float seg = total / n; + float local = t - Mathf.Floor(t / seg) * seg; + float up = (t < seg && fadeIn > 0f) ? Mathf.Min(fadeIn, seg * 0.5f) : seg * 0.5f; + if (local < up) return Mathf.Clamp01(local / up); + float down = seg - up; + return down <= 0f ? 0f : Mathf.Clamp01(1f - (local - up) / down); + } + + private void SetBannerAlpha(float a) + { + if (group == null) return; + group.alpha = a; + group.blocksRaycasts = false; + group.interactable = false; + } + + /// 프로브 전용 — 카운터와 재트리거 가드를 지운다(에디트 모드는 시간이 흐르지 않는다). + public string ResetDiagnostics() + { + SpawnedSeen = BossSpawnSeen = PhaseSeen = ShowCount = 0; + _lastTrigger = -999f; _shownName = ""; _nameKnown = false; + HideNow(); + return "진단 초기화(가드 해제)"; + } + + public void HideNow() + { + _bannerStart = -1f; _warnStart = -1f; + SetBannerAlpha(0f); + var s = WLBossUiSettings.Instance; + if (_warn != null && _warn.IsBuilt) _warn.SetAlpha(s != null ? s.warnVignetteColor : Color.red, 0f); + if (bannerBox != null) bannerBox.localScale = Vector3.one; + } + + // ── 구성 · 배치 ─────────────────────────────────────────────────────── + /// 없는 자식만 만든다(에디터 오소링과 런타임이 같은 코드를 쓴다). + public bool BuildIfNeeded() + { + if (_rt == null) _rt = GetComponent(); + bool made = false; + + if (group == null) { group = GetComponent(); if (group == null) { group = gameObject.AddComponent(); made = true; } } + + if (bannerBox == null) { bannerBox = WLVignetteUtil.NewChild(_rt, "Banner"); made = true; } + if (bannerBg == null) + { + var bg = WLVignetteUtil.NewChild(bannerBox, "Bg"); + WLVignetteUtil.Stretch(bg); + bannerBg = bg.GetComponent(); + if (bannerBg == null) bannerBg = bg.gameObject.AddComponent(); + bannerBg.raycastTarget = false; + made = true; + } + if (titleLabel == null) + { + var t = WLVignetteUtil.NewChild(bannerBox, "Title"); + titleLabel = t.GetComponent(); + if (titleLabel == null) titleLabel = t.gameObject.AddComponent(); + titleLabel.raycastTarget = false; + titleLabel.alignment = TextAlignmentOptions.Center; + if (font != null) titleLabel.font = font; + made = true; + } + if (nameLabel == null) + { + var t = WLVignetteUtil.NewChild(bannerBox, "Name"); + nameLabel = t.GetComponent(); + if (nameLabel == null) nameLabel = t.gameObject.AddComponent(); + nameLabel.raycastTarget = false; + nameLabel.alignment = TextAlignmentOptions.Center; + if (font != null) nameLabel.font = font; + made = true; + } + + _warn = WLVignetteUtil.Build(_rt, "Warn"); + if (warnRoot == null) { warnRoot = _warn.root; made = true; } + return made; + } + + /// 설정 값(px)을 캔버스 유닛으로 환산해 배너·비네트를 맞춘다. + public string ApplyLayout() + { + if (_rt == null) _rt = GetComponent(); + var s = WLBossUiSettings.Instance; + if (s == null) return "WLBossUiSettings 에셋 없음 — 배치 건너뜀"; + if (bannerBox == null) return "구성 요소 없음 — BuildIfNeeded 먼저"; + + float u = UnitsPerPx(); + + // 루트 = Safe Area 전체(부모 = SafeAreaFitter 가 붙은 WL_HUD) → 비네트가 안전 영역 가장자리를 탄다 + WLVignetteUtil.Stretch(_rt); + _rt.localScale = Vector3.one; + + // 배너 상자 = 상단 가운데 + bannerBox.anchorMin = new Vector2(0.5f, 1f); + bannerBox.anchorMax = new Vector2(0.5f, 1f); + bannerBox.pivot = new Vector2(0.5f, 1f); + bannerBox.anchoredPosition = new Vector2(0f, -s.bannerTopMarginPx * u); + bannerBox.sizeDelta = new Vector2(s.bannerSizePx.x * u, s.bannerSizePx.y * u); + + if (bannerBg != null) + { + bannerBg.color = s.bannerBgColor; + bannerBg.enabled = s.bannerBgColor.a > 0.001f; + } + + float titleH = s.bannerTitleFontPx * u; + float nameH = s.bannerNameFontPx * u; + if (titleLabel != null) + { + var t = titleLabel.rectTransform; + t.anchorMin = new Vector2(0f, 1f); t.anchorMax = new Vector2(1f, 1f); t.pivot = new Vector2(0.5f, 1f); + t.offsetMin = new Vector2(0f, 0f); t.offsetMax = new Vector2(0f, 0f); + t.anchoredPosition = Vector2.zero; + t.sizeDelta = new Vector2(0f, titleH); + titleLabel.fontSize = titleH; + titleLabel.color = s.bannerTitleColor; + titleLabel.text = s.bannerTitleText; + if (font != null && titleLabel.font != font) titleLabel.font = font; + } + if (nameLabel != null) + { + var t = nameLabel.rectTransform; + t.anchorMin = new Vector2(0f, 1f); t.anchorMax = new Vector2(1f, 1f); t.pivot = new Vector2(0.5f, 1f); + t.offsetMin = new Vector2(0f, 0f); t.offsetMax = new Vector2(0f, 0f); + t.anchoredPosition = new Vector2(0f, -titleH); + t.sizeDelta = new Vector2(0f, nameH); + nameLabel.fontSize = nameH; + nameLabel.color = s.bannerNameColor; + if (font != null && nameLabel.font != font) nameLabel.font = font; + } + + if (_warn == null || !_warn.IsBuilt) _warn = WLVignetteUtil.Build(_rt, "Warn"); + WLVignetteUtil.ApplyLayout(_warn, s.warnVignetteThicknessPx, u, s.warnVignetteColor); + if (warnRoot == null) warnRoot = _warn.root; + if (warnRoot != null) warnRoot.SetAsFirstSibling(); // 비네트는 배너 뒤에 + + return "layout banner pos" + bannerBox.anchoredPosition + " size" + bannerBox.sizeDelta + + " unitsPerPx=" + u.ToString("F4") + " warnThickness=" + (s.warnVignetteThicknessPx * u).ToString("F1"); + } + + public float UnitsPerPx() + { + if (_canvas == null) _canvas = GetComponentInParent(true); + return WLVignetteUtil.UnitsPerPx(_canvas); + } + + /// 에디터가 폰트를 주입한다(런타임 로드 없음). + public void SetFont(TMP_FontAsset f) + { + font = f; + if (f == null) return; + if (titleLabel != null) titleLabel.font = f; + if (nameLabel != null) nameLabel.font = f; + } + + // ── 검증 전용 (발주서 ⓑ) ───────────────────────────────────────────── + /// 가짜 보스 스폰을 **실제 CombatEvents 경로로** 발행한다(Play 0 검증용). + public static string RaiseFakeBossSpawned() + { + var e = new SpawnedEvent { actor = null, isBoss = true, isElite = false, position = Vector3.zero, time = Time.unscaledTime, frame = Time.frameCount }; + CombatEvents.Spawned.Dispatch(in e); + return "dispatched Spawned(isBoss=true) subscribers=" + CombatEvents.Spawned.Count; + } + + public static string RaiseFakeNonBossSpawned() + { + var e = new SpawnedEvent { actor = null, isBoss = false, isElite = false, position = Vector3.zero, time = Time.unscaledTime, frame = Time.frameCount }; + CombatEvents.Spawned.Dispatch(in e); + return "dispatched Spawned(isBoss=false) subscribers=" + CombatEvents.Spawned.Count; + } + + /// 가짜 보스 페이즈 1 진입(813h 경로) — 이름 승격 검증용. + public static string RaiseFakeBossPhaseSpawn(int monsterId) + { + var e = new BossPhaseEvent + { + boss = null, monsterId = monsterId, prevPhase = 0, phase = 1, phaseCount = 3, + hpPercent = 1f, threshold = 1f, isSpawn = true, time = Time.unscaledTime, frame = Time.frameCount + }; + BossEvents.BossPhase.Dispatch(in e); + return "dispatched BossPhase(isSpawn=true id=" + monsterId + ") subscribers=" + BossEvents.BossPhase.Count; + } + + public string Dump() + { + var sb = new StringBuilder(); + var s = WLBossUiSettings.Instance; + sb.AppendLine("[BossBanner] subscribed=" + _subscribed + " visible=" + Visible + + " bannerAlpha=" + BannerAlpha.ToString("F3") + " warnAlpha=" + WarnAlpha.ToString("F3") + + " scale=" + BannerScale.ToString("F3") + + " name=\"" + _shownName + "\"(known=" + _nameKnown + ")" + + " seen(Spawned/Boss/Phase)=" + SpawnedSeen + "/" + BossSpawnSeen + "/" + PhaseSeen + + " shows=" + ShowCount); + sb.AppendLine(" 구독자 Spawned=" + CombatEvents.Spawned.Count + " BossPhase=" + BossEvents.BossPhase.Count + + " CombatEvents.Enabled=" + CombatEvents.Enabled + " BossEvents.Enabled=" + BossEvents.Enabled); + if (bannerBox != null) + sb.AppendLine(" banner pos" + bannerBox.anchoredPosition + " size" + bannerBox.sizeDelta + + " aMin" + bannerBox.anchorMin + " title=\"" + (titleLabel != null ? titleLabel.text : "-") + + "\" fs=" + (titleLabel != null ? titleLabel.fontSize.ToString("F1") : "-") + + " nameActive=" + (nameLabel != null && nameLabel.gameObject.activeSelf)); + if (_warn != null && _warn.IsBuilt) + for (int i = 0; i < _warn.strips.Length; i++) + { + var img = _warn.strips[i]; + if (img == null) continue; + var r = img.rectTransform; + sb.AppendLine(" warn[" + img.name + "] size" + r.sizeDelta + " aMin" + r.anchorMin + " aMax" + r.anchorMax + + " scale" + r.localScale + " enabled=" + img.enabled + " a=" + img.color.a.ToString("F3") + + " sprite=" + (img.sprite != null ? img.sprite.name : "(없음)") + " raycast=" + img.raycastTarget); + } + sb.AppendLine(" 설정 " + (s == null ? "(에셋 없음)" : + "banner=" + s.bannerSeconds + "s warn=" + s.warnVignetteSeconds + "s topPx=" + s.bannerTopMarginPx + + " sizePx=" + s.bannerSizePx + " thickPx=" + s.warnVignetteThicknessPx + " pulses=" + s.warnVignettePulses)); + return sb.ToString(); + } + } +} diff --git a/Assets/WL/UI/Scripts/BossBanner.cs.meta b/Assets/WL/UI/Scripts/BossBanner.cs.meta new file mode 100644 index 000000000..1d740c678 --- /dev/null +++ b/Assets/WL/UI/Scripts/BossBanner.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: be56aa9524b103044b91f08a879a1502 \ No newline at end of file diff --git a/Assets/WL/UI/Scripts/HitVignette.cs b/Assets/WL/UI/Scripts/HitVignette.cs new file mode 100644 index 000000000..d8a198d83 --- /dev/null +++ b/Assets/WL/UI/Scripts/HitVignette.cs @@ -0,0 +1,287 @@ +// ───────────────────────────────────────────────────────────────────────────── +// HitVignette.cs — 피격 연출: HP 바 붉은 테두리 0.3 s + 화면 가장자리 비네트 (WL-813tj · 813j · #813) +// +// 기준서 v1 §D-1 813j 행: "HP 바 붉은 테두리(피격 0.3 s · UI 이미지 · 포스트 금지)" +// §B 요소 8 위험: 무적 해제 뒤 "맞고 있다"가 화면에 보여야 회복·회피·부활이 의미를 갖는다. +// +// ■ 이벤트 (구독만) +// WL.Combat.Core.CombatEvents.Damaged — 실측 발생 지점 `Assets/Script/Character/MyActor.cs:309` +// = **PC 전용**(MyActor)이라 몹 피격이 섞이지 않는다. 페이로드의 invincible 이 무적 분기를 알려준다. +// 🔴 Q1 QA 실측: playerInvincible=1 인 동안 PC 피격 2045회가 전부 dmg=0 으로 들어온다 +// → 기본값 ignoreInvincibleHits=true 로 무적 피격을 버린다(813i 가 무적을 풀면 저절로 살아난다). +// +// ■ 붉은 테두리의 대상 +// 실측 PC HP 바 = `Common/MyInfoUI/Slider_hp` (295×12 px · MyInfoUI 는 좌상단 (117.9, −44.9)). +// 813tj 가 Common 을 `WL_SafeArea_Back` 아래로 옮겼으므로 경로 탐색은 Safe Area 패널을 건너뛴다 +// (WLVignetteUtil.FindUiPath). 테두리 노드는 **런타임에** 바 자식으로 만든다 — +// NewGameUI.prefab 에 굽지 않는다(ⓓ diff 최소 · 813c/813g 규칙). +// +// ■ 값 = WLSurvivalUiSettings.asset (C45) · 시간 = Time.unscaledTime(히트스톱 무관) +// 🔴 어셈블리 주의: Assets/WL/UI/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일). +// ───────────────────────────────────────────────────────────────────────────── + +using System.Text; +using UnityEngine; +using UnityEngine.UI; +using WL.Combat.Core; + +namespace WL.UI +{ + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class HitVignette : MonoBehaviour + { + public const string BorderNodeName = "WL_HitBorder"; + + [SerializeField] private RectTransform vignetteRoot; + + private RectTransform _rt; + private Canvas _canvas; + private WLEdgeVignette _edge; + private WLEdgeVignette _border; // HP 바 둘레 4띠(단색) + private RectTransform _borderRoot; + private bool _subscribed; + private float _edgeStart = -1f, _borderStart = -1f, _lastHit = -999f; + + // ── 진단 ────────────────────────────────────────────────────────────── + public int DamagedSeen { get; private set; } + public int InvincibleSkipped { get; private set; } + public int ThrottleSkipped { get; private set; } + public int FlashCount { get; private set; } + public string BorderTargetPath { get; private set; } = ""; + public bool BorderBound { get { return _border != null && _border.IsBuilt; } } + public float EdgeAlpha { get { return _edge != null ? _edge.CurrentAlpha : 0f; } } + public float BorderAlpha { get { return _border != null ? _border.CurrentAlpha : 0f; } } + + private void Awake() { _rt = GetComponent(); } + private void OnEnable() { Initialize(); } + private void OnDisable() { Subscribe(false); } + + /// OnEnable 본체(에디트 모드 검증이 같은 경로를 탄다 · 813c 교훈). 테두리도 여기서 만든다. + public string Initialize() + { + if (_rt == null) _rt = GetComponent(); + BuildIfNeeded(); + string layout = ApplyLayout(); + string border = EnsureBorder(); + HideNow(); + var s = WLSurvivalUiSettings.Instance; + Subscribe(s == null || s.hitFeedbackEnabled); + return "initialized subscribed=" + _subscribed + " · " + layout + " · " + border; + } + + public void Subscribe(bool on) + { + if (on == _subscribed) return; + _subscribed = on; + if (on) CombatEvents.Damaged.Add(OnDamaged); + else CombatEvents.Damaged.Remove(OnDamaged); + } + + // ── 구독 ────────────────────────────────────────────────────────────── + private void OnDamaged(in DamagedEvent e) + { + DamagedSeen++; + var s = WLSurvivalUiSettings.Instance; + if (s == null || !s.hitFeedbackEnabled) return; + if (e.invincible && s.ignoreInvincibleHits) { InvincibleSkipped++; return; } + + float now = Time.unscaledTime; + if (now - _lastHit < s.hitMinIntervalSeconds) { ThrottleSkipped++; return; } + Flash(now); + } + + /// 피격 번쩍임 1회(테두리 + 가장자리). 프로브가 직접 부르기도 한다. + public string Flash(float now) + { + var s = WLSurvivalUiSettings.Instance; + if (s == null) return "WLSurvivalUiSettings 에셋 없음 — 표시 안 함"; + _lastHit = now; + FlashCount++; + _borderStart = s.hitBorderEnabled ? now : -1f; + _edgeStart = s.hitVignetteEnabled ? now : -1f; + if (_borderStart >= 0f && !BorderBound) EnsureBorder(); + Tick(now); + if (s.verboseLog) Debug.Log("[HitVignette] flash border=" + s.hitBorderSeconds + "s edge=" + s.hitVignetteSeconds + "s"); + return "flash border=" + (_borderStart >= 0f ? s.hitBorderSeconds.ToString("F2") + "s" : "off") + + " edge=" + (_edgeStart >= 0f ? s.hitVignetteSeconds.ToString("F2") + "s" : "off") + + " bound=" + BorderBound; + } + + private void Update() { Tick(Time.unscaledTime); } + + /// 알파 감쇠 진행. 프로브가 시간을 넣어 같은 경로로 검증한다. + public void Tick(float now) + { + var s = WLSurvivalUiSettings.Instance; + if (s == null) return; + + if (_borderStart >= 0f && _border != null && _border.IsBuilt) + { + float t = now - _borderStart; + if (t >= s.hitBorderSeconds) { _borderStart = -1f; _border.SetAlpha(s.hitBorderColor, 0f); } + else _border.SetAlpha(s.hitBorderColor, 1f - Mathf.Clamp01(t / s.hitBorderSeconds)); + } + if (_edgeStart >= 0f && _edge != null && _edge.IsBuilt) + { + float t = now - _edgeStart; + if (t >= s.hitVignetteSeconds) { _edgeStart = -1f; _edge.SetAlpha(s.hitVignetteColor, 0f); } + else _edge.SetAlpha(s.hitVignetteColor, 1f - Mathf.Clamp01(t / s.hitVignetteSeconds)); + } + } + + public void HideNow() + { + _edgeStart = -1f; _borderStart = -1f; + var s = WLSurvivalUiSettings.Instance; + if (_edge != null && _edge.IsBuilt) _edge.SetAlpha(s != null ? s.hitVignetteColor : Color.red, 0f); + if (_border != null && _border.IsBuilt) _border.SetAlpha(s != null ? s.hitBorderColor : Color.red, 0f); + } + + // ── 구성 · 배치 ─────────────────────────────────────────────────────── + /// 자기 노드 아래 가장자리 비네트만 만든다(HP 바 테두리는 EnsureBorder 가 런타임에). + public bool BuildIfNeeded() + { + if (_rt == null) _rt = GetComponent(); + _edge = WLVignetteUtil.Build(_rt, "Edge"); + bool made = vignetteRoot == null; + if (vignetteRoot == null) vignetteRoot = _edge.root; + return made; + } + + public string ApplyLayout() + { + if (_rt == null) _rt = GetComponent(); + var s = WLSurvivalUiSettings.Instance; + if (s == null) return "WLSurvivalUiSettings 에셋 없음 — 배치 건너뜀"; + + WLVignetteUtil.Stretch(_rt); + _rt.localScale = Vector3.one; + + float u = UnitsPerPx(); + if (_edge == null || !_edge.IsBuilt) _edge = WLVignetteUtil.Build(_rt, "Edge"); + WLVignetteUtil.ApplyLayout(_edge, s.hitVignetteThicknessPx, u, s.hitVignetteColor); + if (vignetteRoot == null) vignetteRoot = _edge.root; + return "layout edgeThickness=" + (s.hitVignetteThicknessPx * u).ToString("F1") + " unitsPerPx=" + u.ToString("F4"); + } + + /// + /// HP 바를 찾아 그 둘레에 붉은 테두리 4띠를 만든다(런타임 전용 · 프리팹에 굽지 않는다). + /// Safe Area 재부모화 뒤에도 옛 경로 문자열이 그대로 먹도록 WLVignetteUtil.FindUiPath 를 쓴다. + /// + public string EnsureBorder() + { + var s = WLSurvivalUiSettings.Instance; + if (s == null || !s.hitBorderEnabled) return "테두리 off"; + + var canvasRoot = WLVignetteUtil.FindCanvasRoot(transform); + var target = WLVignetteUtil.FindUiPath(canvasRoot, s.hitBorderTargetPath) as Transform; + var targetRt = target as RectTransform; + if (targetRt == null) + { + BorderTargetPath = "(못 찾음) " + s.hitBorderTargetPath; + return "🔴 HP 바 경로 없음: " + s.hitBorderTargetPath + " — 테두리 생략(가장자리 비네트는 그대로)"; + } + BorderTargetPath = GetPath(canvasRoot, targetRt); + + float u = UnitsPerPx(); + float t = Mathf.Max(0f, s.hitBorderThicknessPx) * u; + + _border = WLVignetteUtil.Build(targetRt, BorderNodeName); + _borderRoot = _border.root; + if (_borderRoot != null) + { + // 바 바깥으로 두께만큼 벌린 사각형 → 그 안쪽 가장자리 4띠가 곧 테두리가 된다 + _borderRoot.anchorMin = Vector2.zero; _borderRoot.anchorMax = Vector2.one; + _borderRoot.pivot = new Vector2(0.5f, 0.5f); + _borderRoot.offsetMin = new Vector2(-t, -t); + _borderRoot.offsetMax = new Vector2(t, t); + _borderRoot.localScale = Vector3.one; + } + WLVignetteUtil.ApplyLayout(_border, s.hitBorderThicknessPx, u, s.hitBorderColor); + // 테두리는 그라디언트가 아니라 단색이어야 "테두리" 로 읽힌다 + for (int i = 0; i < _border.strips.Length; i++) + if (_border.strips[i] != null) _border.strips[i].sprite = null; + + _border.SetAlpha(s.hitBorderColor, 0f); + return "테두리 부착 " + BorderTargetPath + " thickness=" + t.ToString("F1") + "u(" + s.hitBorderThicknessPx + "px)"; + } + + /// 런타임에 만든 테두리 노드를 지운다(C8 롤백 · 프로브 정리용). + public string RemoveBorder() + { + if (_borderRoot == null) + { + var canvasRoot = WLVignetteUtil.FindCanvasRoot(transform); + var s = WLSurvivalUiSettings.Instance; + var target = s != null ? WLVignetteUtil.FindUiPath(canvasRoot, s.hitBorderTargetPath) : null; + if (target != null) _borderRoot = target.Find(BorderNodeName) as RectTransform; + } + if (_borderRoot == null) return "테두리 없음"; + var go = _borderRoot.gameObject; + _borderRoot = null; _border = null; + if (Application.isPlaying) Destroy(go); else DestroyImmediate(go); + return "테두리 제거"; + } + + private static string GetPath(Transform root, Transform t) + { + var sb = new StringBuilder(t.name); + var cur = t.parent; + while (cur != null && cur != root) { sb.Insert(0, cur.name + "/"); cur = cur.parent; } + return sb.ToString(); + } + + public float UnitsPerPx() + { + if (_canvas == null) _canvas = GetComponentInParent(true); + return WLVignetteUtil.UnitsPerPx(_canvas); + } + + // ── 검증 전용 ──────────────────────────────────────────────────────── + /// 가짜 PC 피격을 **실제 CombatEvents 경로로** 발행한다(Play 0 검증용). + public static string RaiseFakeDamaged(double damage, bool invincible) + { + var e = new DamagedEvent + { + victim = null, attacker = null, dinfo = null, damage = damage, + invincible = invincible, time = Time.unscaledTime, frame = Time.frameCount + }; + CombatEvents.Damaged.Dispatch(in e); + return "dispatched Damaged(dmg=" + damage + " invincible=" + invincible + ") subscribers=" + CombatEvents.Damaged.Count; + } + + public string Dump() + { + var sb = new StringBuilder(); + var s = WLSurvivalUiSettings.Instance; + sb.AppendLine("[HitVignette] subscribed=" + _subscribed + " flashes=" + FlashCount + + " seen=" + DamagedSeen + " 무적스킵=" + InvincibleSkipped + " 스로틀스킵=" + ThrottleSkipped + + " edgeAlpha=" + EdgeAlpha.ToString("F3") + " borderAlpha=" + BorderAlpha.ToString("F3")); + sb.AppendLine(" 구독자 Damaged=" + CombatEvents.Damaged.Count + " Enabled=" + CombatEvents.Enabled); + sb.AppendLine(" 테두리 대상=" + (string.IsNullOrEmpty(BorderTargetPath) ? "(미탐색)" : BorderTargetPath) + " bound=" + BorderBound); + if (_borderRoot != null) + sb.AppendLine(" 테두리 root offMin" + _borderRoot.offsetMin + " offMax" + _borderRoot.offsetMax + + " rect=" + _borderRoot.rect.width.ToString("F1") + "x" + _borderRoot.rect.height.ToString("F1")); + if (_edge != null && _edge.IsBuilt) + for (int i = 0; i < _edge.strips.Length; i++) + { + var img = _edge.strips[i]; if (img == null) continue; + sb.AppendLine(" edge[" + img.name + "] size" + img.rectTransform.sizeDelta + " scale" + img.rectTransform.localScale + + " enabled=" + img.enabled + " a=" + img.color.a.ToString("F3") + " raycast=" + img.raycastTarget); + } + if (_border != null && _border.IsBuilt) + for (int i = 0; i < _border.strips.Length; i++) + { + var img = _border.strips[i]; if (img == null) continue; + sb.AppendLine(" border[" + img.name + "] size" + img.rectTransform.sizeDelta + + " enabled=" + img.enabled + " a=" + img.color.a.ToString("F3") + + " sprite=" + (img.sprite != null ? img.sprite.name : "(단색)")); + } + sb.AppendLine(" 설정 " + (s == null ? "(에셋 없음)" : + "border=" + s.hitBorderSeconds + "s/" + s.hitBorderThicknessPx + "px edge=" + s.hitVignetteSeconds + "s/" + + s.hitVignetteThicknessPx + "px 무적무시=" + s.ignoreInvincibleHits + " 스로틀=" + s.hitMinIntervalSeconds + "s")); + return sb.ToString(); + } + } +} diff --git a/Assets/WL/UI/Scripts/HitVignette.cs.meta b/Assets/WL/UI/Scripts/HitVignette.cs.meta new file mode 100644 index 000000000..41d3a28df --- /dev/null +++ b/Assets/WL/UI/Scripts/HitVignette.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 863efecd89e890e448a36adf35578b68 \ No newline at end of file diff --git a/Assets/WL/UI/Scripts/PotionButton.cs b/Assets/WL/UI/Scripts/PotionButton.cs new file mode 100644 index 000000000..7b081e363 --- /dev/null +++ b/Assets/WL/UI/Scripts/PotionButton.cs @@ -0,0 +1,333 @@ +// ───────────────────────────────────────────────────────────────────────────── +// PotionButton.cs — 전투 패드 물약 버튼(잔량 + 쿨 링) (WL-813tj · 813j · #813) +// +// 기준서 v1 §D-1 813j 행: "813c 의 빈 자리에 물약 버튼(잔량 · 쿨 링)" +// §B 요소 8: 물약 3개/런 · 40 % 회복 · 쿨 5 s. +// +// ■ 자리 (813c 소유) +// 813c 가 전투 패드 6슬롯 중 4를 스킬로 쓰고 **2를 예약**(물약 · 회피)으로 비활성화했다. +// 이 버튼은 그 예약 좌표(`WLHudLayoutSettings.ReserveSlotPx(index)`)에 **자기 노드**로 앉는다. +// 비활성 SkillCard 를 되살려 쓰지 않는 이유: `WLBattlePadLayout.Apply()` 가 매번 예약 슬롯을 +// SetActive(false) 로 되돌리기 때문(813c 실측) — 켜 두면 두 코드가 서로 끈다. +// +// ■ 🔴 데이터는 813i(Gameplay) 가 주인 — 이 파일은 표시만 한다 +// `WL.Combat.Survival.PotionUse` 는 **아직 없다**(브랜치 `wl/gameplay/WL-813i-survival` 은 +// 2026-09-09 01:4x 기준 main 대비 커밋 0 · `Assets/WL/Combat/Survival/*.cs` 없음 = 실측). +// 존재하지 않는 타입을 참조하면 게이트가 깨지므로, **정적 델리게이트 자리**만 열어 둔다. +// 813i 는 자기 파일에서 아래 4개를 채우면 끝난다(UI 수정 0): +// PotionButton.CountProvider = () => PotionUse.Remain; +// PotionButton.CooldownRemainProvider = () => PotionUse.CooldownRemain; +// PotionButton.CooldownTotalProvider = () => PotionUse.CooldownTotal; +// PotionButton.UseHandler = () => PotionUse.TryUse(); +// Provider 가 없으면 설정의 표시용 기본값(3개 · 5 s)을 그리고, 클릭은 무동작이다(오동작 방지). +// +// ■ 값 = WLSurvivalUiSettings.asset + 자리 = WLHudLayoutSettings.asset (둘 다 C45) +// 🔴 어셈블리 주의: Assets/WL/UI/ 에 .asmdef 를 만들지 말 것(Assembly-CSharp 단일). +// ───────────────────────────────────────────────────────────────────────────── + +using System.Text; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace WL.UI +{ + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class PotionButton : MonoBehaviour + { + // ── 813i 연결점 (「후속」 · 존재하지 않는 타입을 참조하지 않는다) ───── + /// 남은 물약 개수. 813i 가 채운다. + public static System.Func CountProvider; + /// 남은 쿨(초). 813i 가 채운다. + public static System.Func CooldownRemainProvider; + /// 쿨 전체 길이(초). 813i 가 채운다. + public static System.Func CooldownTotalProvider; + /// 실제 사용. true = 소비 성공. 813i 가 채운다. + public static System.Func UseHandler; + /// 버튼을 눌렀다는 통지(로그·튜토리얼용 · 선택). + public static System.Action UseRequested; + + /// 813i 가 연결됐는가(진단·완료보고 근거). + public static bool HasProvider { get { return CountProvider != null || UseHandler != null; } } + + [Header("구성 요소 (BuildIfNeeded 가 만든다)")] + [SerializeField] private Image background; + [SerializeField] private Image cooldownRing; + [SerializeField] private TextMeshProUGUI iconLabel; + [SerializeField] private TextMeshProUGUI countLabel; + [SerializeField] private Button button; + [SerializeField] private CanvasGroup group; + + [Header("폰트 (에디터가 주입)")] + [SerializeField] private TMP_FontAsset font; + + private RectTransform _rt; + private Canvas _canvas; + private int _lastCount = -1; + private float _lastFill = -1f; + + // ── 진단 ────────────────────────────────────────────────────────────── + public int ClickCount { get; private set; } + public int UsedCount { get; private set; } + public int BlockedCount { get; private set; } + public int ShownCount { get { return _lastCount; } } + public float ShownFill { get { return _lastFill; } } + + private void Awake() { _rt = GetComponent(); } + private void OnEnable() { Initialize(); } + + public string Initialize() + { + if (_rt == null) _rt = GetComponent(); + BuildIfNeeded(); + string layout = ApplyLayout(); + Refresh(); + return "initialized · " + layout + " · provider=" + HasProvider; + } + + // ── 값 읽기 (813i 있으면 그쪽 · 없으면 표시용 기본값) ──────────────── + public int ReadCount() + { + if (CountProvider != null) { try { return CountProvider(); } catch { } } + var s = WLSurvivalUiSettings.Instance; + return s != null ? s.potionFallbackCount : 0; + } + + public float ReadCooldownFill() + { + var s = WLSurvivalUiSettings.Instance; + float total = 0f, remain = 0f; + if (CooldownTotalProvider != null) { try { total = CooldownTotalProvider(); } catch { } } + if (CooldownRemainProvider != null) { try { remain = CooldownRemainProvider(); } catch { } } + if (total <= 0f) total = s != null ? s.potionFallbackCooldownSeconds : 0f; + if (total <= 0f) return 0f; + return Mathf.Clamp01(remain / total); + } + + private void Update() { Refresh(); } + + /// 잔량·쿨 링·흐림을 현재 값에 맞춘다(값이 그대로면 아무 것도 하지 않는다). + public string Refresh() + { + var s = WLSurvivalUiSettings.Instance; + if (s == null) return "WLSurvivalUiSettings 에셋 없음"; + + int count = ReadCount(); + float fill = ReadCooldownFill(); + bool ready = count > 0 && fill <= 0.0001f; + + if (count != _lastCount) + { + _lastCount = count; + if (countLabel != null) countLabel.text = string.Format(s.potionCountFormat, count); + } + if (!Mathf.Approximately(fill, _lastFill)) + { + _lastFill = fill; + if (cooldownRing != null) + { + cooldownRing.fillAmount = fill; + if (cooldownRing.enabled != (fill > 0.0001f)) cooldownRing.enabled = fill > 0.0001f; + } + } + var tint = ready ? s.potionReadyColor : s.potionDimColor; + if (iconLabel != null) iconLabel.color = tint; + if (countLabel != null) countLabel.color = tint; + if (group != null) group.alpha = ready ? 1f : 0.75f; + return "count=" + count + " fill=" + fill.ToString("F3") + " ready=" + ready; + } + + /// 버튼 클릭. 813i Provider 가 없으면 아무 일도 하지 않는다(설정으로 완화 가능). + public string OnClickPotion() + { + ClickCount++; + var s = WLSurvivalUiSettings.Instance; + if (s == null) return "설정 없음 — 무동작"; + if (UseRequested != null) { try { UseRequested(); } catch { } } + + if (UseHandler == null) + { + BlockedCount++; + if (s.verboseLog) Debug.Log("[PotionButton] 813i(PotionUse) 미연결 — 표시만 (후속)"); + return s.potionRequireProvider ? "813i 미연결 — 무동작(후속)" : "813i 미연결 — 무동작"; + } + bool ok = false; + try { ok = UseHandler(); } catch { ok = false; } + if (ok) UsedCount++; else BlockedCount++; + Refresh(); + return ok ? "사용 성공" : "사용 불가(잔량 0 또는 쿨)"; + } + + // ── 구성 · 배치 ─────────────────────────────────────────────────────── + public bool BuildIfNeeded() + { + if (_rt == null) _rt = GetComponent(); + bool made = false; + + if (group == null) { group = GetComponent(); if (group == null) { group = gameObject.AddComponent(); made = true; } } + if (background == null) + { + background = GetComponent(); + if (background == null) { background = gameObject.AddComponent(); made = true; } + background.raycastTarget = true; + } + if (button == null) + { + button = GetComponent