using System.Collections; using UnityEngine; using UnityEngine.UI; namespace Streamingle.Contents.BossRaid { /// /// 페이즈 전환 컷인 연출. /// 화면 중앙에 페이즈 이름이 슬라이드 인 → 정지 → 슬라이드 아웃. /// public class PhaseTransition : MonoBehaviour { #region Fields [Header("연출 설정")] [SerializeField] private float slideInDuration = 0.3f; [SerializeField] private float holdDuration = 1.0f; [SerializeField] private float slideOutDuration = 0.3f; [Header("비주얼")] [SerializeField] private Color backgroundColor = new Color(0f, 0f, 0f, 0.7f); [SerializeField] private Color textColor = new Color(1f, 0.3f, 0.3f, 1f); [SerializeField] private int fontSize = 72; private Canvas _canvas; private CanvasGroup _canvasGroup; private RectTransform _bgRect; private Text _text; private Coroutine _transitionCoroutine; private Font _font; #endregion #region Unity Messages private void Awake() { _font = BossRaidFontLoader.Load(); CreateUI(); _canvasGroup.alpha = 0f; } #endregion #region Public Methods public void Play(string phaseName) { if (_transitionCoroutine != null) StopCoroutine(_transitionCoroutine); _transitionCoroutine = StartCoroutine(TransitionCoroutine(phaseName)); } #endregion #region Private Methods private void CreateUI() { var canvasObj = new GameObject("BossRaid_PhaseTransition"); canvasObj.transform.SetParent(transform); _canvas = canvasObj.AddComponent(); _canvas.renderMode = RenderMode.ScreenSpaceOverlay; _canvas.sortingOrder = 998; _canvasGroup = canvasObj.AddComponent(); _canvasGroup.interactable = false; _canvasGroup.blocksRaycasts = false; // 배경 바 var bgObj = new GameObject("PhaseTransition_BG"); bgObj.transform.SetParent(canvasObj.transform, false); _bgRect = bgObj.AddComponent(); _bgRect.anchorMin = new Vector2(0f, 0.35f); _bgRect.anchorMax = new Vector2(1f, 0.65f); _bgRect.offsetMin = Vector2.zero; _bgRect.offsetMax = Vector2.zero; var bgImg = bgObj.AddComponent(); bgImg.color = backgroundColor; bgImg.raycastTarget = false; // 텍스트 var textObj = new GameObject("PhaseTransition_Text"); textObj.transform.SetParent(bgObj.transform, false); var textRect = textObj.AddComponent(); textRect.anchorMin = Vector2.zero; textRect.anchorMax = Vector2.one; textRect.offsetMin = Vector2.zero; textRect.offsetMax = Vector2.zero; _text = textObj.AddComponent(); _text.alignment = TextAnchor.MiddleCenter; _text.fontSize = fontSize; _text.color = textColor; _text.fontStyle = FontStyle.Bold; _text.horizontalOverflow = HorizontalWrapMode.Overflow; _text.raycastTarget = false; if (_font != null) _text.font = _font; var outline = textObj.AddComponent(); outline.effectColor = Color.black; outline.effectDistance = new Vector2(3f, -3f); } private IEnumerator TransitionCoroutine(string phaseName) { _text.text = phaseName; float screenWidth = Screen.width; float elapsed = 0f; while (elapsed < slideInDuration) { elapsed += Time.unscaledDeltaTime; float t = elapsed / slideInDuration; float ease = 1f - (1f - t) * (1f - t); _canvasGroup.alpha = ease; _bgRect.anchoredPosition = new Vector2(Mathf.Lerp(screenWidth, 0f, ease), 0f); yield return null; } _canvasGroup.alpha = 1f; _bgRect.anchoredPosition = Vector2.zero; yield return new WaitForSecondsRealtime(holdDuration); elapsed = 0f; while (elapsed < slideOutDuration) { elapsed += Time.unscaledDeltaTime; float t = elapsed / slideOutDuration; float ease = t * t; _canvasGroup.alpha = 1f - ease; _bgRect.anchoredPosition = new Vector2(Mathf.Lerp(0f, -screenWidth, ease), 0f); yield return null; } _canvasGroup.alpha = 0f; _transitionCoroutine = null; } #endregion } }