using BumpCombat.Audio; using BumpCombat.Core; using BumpCombat.Progression; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; namespace BumpCombat.UI { public sealed class RunClearPanel : MonoBehaviour { private GameObject panel; private Text titleText; private Text statsText; private Text restartText; private bool isShown; private void Start() { CreatePanel(); if (RunManager.Instance != null) { RunManager.Instance.OnRunCleared += HandleRunCleared; } } private void OnDestroy() { if (RunManager.Instance != null) { RunManager.Instance.OnRunCleared -= HandleRunCleared; } } private void Update() { if (!isShown || Keyboard.current == null) { return; } if (Keyboard.current.rKey.wasPressedThisFrame) { RunManager.Instance?.RestartRun(); } else if (Keyboard.current.escapeKey.wasPressedThisFrame) { RunManager.Instance?.RestartToTitle(); } } private void HandleRunCleared() { isShown = true; panel.SetActive(true); BumpCombatAudioService.Instance?.PlayUi("ui_confirm"); float elapsed = RunManager.Instance != null ? RunManager.Instance.ElapsedTime : 0f; int minutes = Mathf.FloorToInt(elapsed / 60f); int seconds = Mathf.FloorToInt(elapsed % 60f); ExperienceSystem exp = FindAnyObjectByType(); int level = exp != null ? exp.Level : 1; statsText.text = RunManager.Instance != null && RunManager.Instance.IsDefensePrototypeRun ? $"CLEAR TIME: {minutes:D2}:{seconds:D2}\nCONSTRUCTION REWARD COLLECTED\nDEFENSE TEST CLEARED" : $"CLEAR TIME: {minutes:D2}:{seconds:D2}\nFINAL LEVEL: LV {level}\nSTAGE: 3 / 3 COMPLETED"; } private void CreatePanel() { Canvas canvas = GetComponentInParent() ?? FindAnyObjectByType(); if (canvas == null) { return; } panel = new GameObject("RunClearPanel"); panel.transform.SetParent(canvas.transform, false); RectTransform panelRect = panel.AddComponent(); panelRect.anchorMin = Vector2.zero; panelRect.anchorMax = Vector2.one; panelRect.offsetMin = Vector2.zero; panelRect.offsetMax = Vector2.zero; // Background dark dim with gold tint Image bg = panel.AddComponent(); bg.color = new Color(0.08f, 0.08f, 0.04f, 0.94f); // Title GameObject titleObj = new GameObject("ClearTitle"); titleObj.transform.SetParent(panel.transform, false); titleText = titleObj.AddComponent(); titleText.font = Resources.GetBuiltinResource("LegacyRuntime.ttf"); titleText.fontSize = 42; titleText.fontStyle = FontStyle.Bold; titleText.alignment = TextAnchor.MiddleCenter; titleText.color = new Color(1f, 0.85f, 0.25f); titleText.text = RunManager.Instance != null && RunManager.Instance.IsDefensePrototypeRun ? "★ DEFENSE TEST CLEARED ★" : "★ RUN CLEAR ★"; RectTransform titleRect = titleObj.GetComponent(); titleRect.anchorMin = new Vector2(0f, 0.6f); titleRect.anchorMax = new Vector2(1f, 0.8f); titleRect.offsetMin = Vector2.zero; titleRect.offsetMax = Vector2.zero; // Stats GameObject statsObj = new GameObject("ClearStats"); statsObj.transform.SetParent(panel.transform, false); statsText = statsObj.AddComponent(); statsText.font = Resources.GetBuiltinResource("LegacyRuntime.ttf"); statsText.fontSize = 20; statsText.alignment = TextAnchor.MiddleCenter; statsText.color = new Color(0.9f, 0.9f, 0.95f); statsText.lineSpacing = 1.4f; RectTransform statsRect = statsObj.GetComponent(); statsRect.anchorMin = new Vector2(0.1f, 0.35f); statsRect.anchorMax = new Vector2(0.9f, 0.55f); statsRect.offsetMin = Vector2.zero; statsRect.offsetMax = Vector2.zero; // Restart Hint GameObject restartObj = new GameObject("ClearRestartHint"); restartObj.transform.SetParent(panel.transform, false); restartText = restartObj.AddComponent(); restartText.font = Resources.GetBuiltinResource("LegacyRuntime.ttf"); restartText.fontSize = 16; restartText.alignment = TextAnchor.MiddleCenter; restartText.color = new Color(0.7f, 0.7f, 0.75f); restartText.text = "[R] 키로 재시작 | [ESC] 키로 타이틀로 이동"; RectTransform restartRect = restartObj.GetComponent(); restartRect.anchorMin = new Vector2(0f, 0.15f); restartRect.anchorMax = new Vector2(1f, 0.25f); restartRect.offsetMin = Vector2.zero; restartRect.offsetMax = Vector2.zero; panel.SetActive(false); } } }