141 lines
4.8 KiB
C#

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace Streamingle.Contents.BossRaid
{
/// <summary>
/// 페이즈 전환 컷인 연출.
/// 화면 중앙에 페이즈 이름이 슬라이드 인 → 정지 → 슬라이드 아웃.
/// </summary>
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>();
_canvas.renderMode = RenderMode.ScreenSpaceOverlay;
_canvas.sortingOrder = 998;
_canvasGroup = canvasObj.AddComponent<CanvasGroup>();
_canvasGroup.interactable = false;
_canvasGroup.blocksRaycasts = false;
// 배경 바
var bgObj = new GameObject("PhaseTransition_BG");
bgObj.transform.SetParent(canvasObj.transform, false);
_bgRect = bgObj.AddComponent<RectTransform>();
_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<Image>();
bgImg.color = backgroundColor;
bgImg.raycastTarget = false;
// 텍스트
var textObj = new GameObject("PhaseTransition_Text");
textObj.transform.SetParent(bgObj.transform, false);
var textRect = textObj.AddComponent<RectTransform>();
textRect.anchorMin = Vector2.zero;
textRect.anchorMax = Vector2.one;
textRect.offsetMin = Vector2.zero;
textRect.offsetMax = Vector2.zero;
_text = textObj.AddComponent<Text>();
_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>();
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
}
}