using System.Collections; using UnityEngine; using UnityEngine.UI; namespace Streamingle.Contents.BossRaid { /// /// 승리 결과 화면 UI. /// "YOU WIN!" + 전투 스탯 요약. /// public class VictoryScreen : MonoBehaviour { #region Fields [Header("설정")] [SerializeField] private float titleAppearDelay = 0.3f; [SerializeField] private float statsAppearDelay = 0.8f; [SerializeField] private float statLineInterval = 0.2f; [Header("비주얼")] [SerializeField] private Color titleColor = new Color(1f, 0.85f, 0.2f); [SerializeField] private Color statLabelColor = new Color(0.7f, 0.7f, 0.7f); [SerializeField] private Color statValueColor = new Color(0.3f, 1f, 0.5f); private Canvas _canvas; private CanvasGroup _canvasGroup; private Text _titleText; private Text _statsText; private Coroutine _showCoroutine; private Font _font; #endregion #region Unity Messages private void Awake() { _font = BossRaidFontLoader.Load(); CreateUI(); _canvasGroup.alpha = 0f; } #endregion #region Public Methods public void Show(BossRaidResult result) { if (_showCoroutine != null) StopCoroutine(_showCoroutine); _showCoroutine = StartCoroutine(ShowCoroutine(result)); } public void Hide() { if (_showCoroutine != null) { StopCoroutine(_showCoroutine); _showCoroutine = null; } _canvasGroup.alpha = 0f; } #endregion #region Private Methods private IEnumerator ShowCoroutine(BossRaidResult result) { _canvasGroup.alpha = 1f; _titleText.text = ""; _statsText.text = ""; yield return new WaitForSecondsRealtime(titleAppearDelay); _titleText.text = "YOU WIN!"; yield return StartCoroutine(PunchScale(_titleText.rectTransform, 0.4f, 1.5f)); yield return new WaitForSecondsRealtime(statsAppearDelay); string[] lines = new string[] { $"Boss: {result.bossName}", $"Time: {FormatTime(result.elapsedTime)}", $"Total Damage: {result.totalDamage:N0}", $"Hits: {result.hitCount}", $"Criticals: {result.criticalCount}", $"Max Combo: {result.maxCombo}", }; _statsText.text = ""; foreach (var line in lines) { _statsText.text += line + "\n"; yield return new WaitForSecondsRealtime(statLineInterval); } } private IEnumerator PunchScale(RectTransform rect, float duration, float punchSize) { Vector3 baseScale = Vector3.one; Vector3 punchScale = baseScale * punchSize; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; float t = elapsed / duration; float ease = 1f - Mathf.Pow(2f, -10f * t) * Mathf.Cos(t * Mathf.PI * 3f); rect.localScale = Vector3.LerpUnclamped(punchScale, baseScale, ease); yield return null; } rect.localScale = baseScale; } private string FormatTime(float seconds) { int min = Mathf.FloorToInt(seconds / 60f); float sec = seconds % 60f; return min > 0 ? $"{min}m {sec:F1}s" : $"{sec:F1}s"; } private void CreateUI() { var canvasObj = new GameObject("BossRaid_VictoryScreen"); canvasObj.transform.SetParent(transform); _canvas = canvasObj.AddComponent(); _canvas.renderMode = RenderMode.ScreenSpaceOverlay; _canvas.sortingOrder = 200; _canvasGroup = canvasObj.AddComponent(); _canvasGroup.interactable = false; _canvasGroup.blocksRaycasts = false; var scaler = canvasObj.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1920, 1080); // 배경 var bgObj = new GameObject("Victory_BG"); bgObj.transform.SetParent(canvasObj.transform, false); var bgRect = bgObj.AddComponent(); bgRect.anchorMin = Vector2.zero; bgRect.anchorMax = Vector2.one; bgRect.offsetMin = Vector2.zero; bgRect.offsetMax = Vector2.zero; var bgImg = bgObj.AddComponent(); bgImg.color = new Color(0f, 0f, 0f, 0.5f); bgImg.raycastTarget = false; // 타이틀 var titleObj = new GameObject("Victory_Title"); titleObj.transform.SetParent(canvasObj.transform, false); var titleRect = titleObj.AddComponent(); titleRect.anchorMin = new Vector2(0.1f, 0.55f); titleRect.anchorMax = new Vector2(0.9f, 0.85f); titleRect.offsetMin = Vector2.zero; titleRect.offsetMax = Vector2.zero; _titleText = titleObj.AddComponent(); _titleText.fontSize = 80; _titleText.color = titleColor; _titleText.alignment = TextAnchor.MiddleCenter; _titleText.fontStyle = FontStyle.Bold; _titleText.raycastTarget = false; if (_font != null) _titleText.font = _font; var titleOutline = titleObj.AddComponent(); titleOutline.effectColor = Color.black; titleOutline.effectDistance = new Vector2(3f, -3f); // 스탯 var statsObj = new GameObject("Victory_Stats"); statsObj.transform.SetParent(canvasObj.transform, false); var statsRect = statsObj.AddComponent(); statsRect.anchorMin = new Vector2(0.25f, 0.1f); statsRect.anchorMax = new Vector2(0.75f, 0.55f); statsRect.offsetMin = Vector2.zero; statsRect.offsetMax = Vector2.zero; _statsText = statsObj.AddComponent(); _statsText.fontSize = 28; _statsText.color = statValueColor; _statsText.alignment = TextAnchor.UpperCenter; _statsText.lineSpacing = 1.5f; _statsText.raycastTarget = false; if (_font != null) _statsText.font = _font; var statsOutline = statsObj.AddComponent(); statsOutline.effectColor = new Color(0f, 0f, 0f, 0.8f); statsOutline.effectDistance = new Vector2(1f, -1f); } #endregion } }