207 lines
6.8 KiB
C#
207 lines
6.8 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.SceneManagement;
|
|||
|
|
using System.Collections;
|
|||
|
|
using TMPro;
|
|||
|
|
|
|||
|
|
public class SceneLoader : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
// =========================
|
|||
|
|
// 싱글톤(전역 접근용)
|
|||
|
|
// =========================
|
|||
|
|
public static SceneLoader Instance;
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// 로딩 UI 연결
|
|||
|
|
// =========================
|
|||
|
|
[Header("로딩 UI 연결")]
|
|||
|
|
public GameObject loadingCanvas; // 하이어라키의 'load canvas' 전체(로딩 화면 전체)
|
|||
|
|
public CanvasGroup backgroundGroup; // 배경(검정 페이드)용 CanvasGroup
|
|||
|
|
public TextMeshProUGUI tipText; // Tip 텍스트(TMP)
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// 로딩 시 나타날 요소들
|
|||
|
|
// =========================
|
|||
|
|
[Header("로딩 시 나타날 요소들")]
|
|||
|
|
public GameObject loadingTextObject; // "Loading..." 텍스트 오브젝트
|
|||
|
|
public GameObject tipBarObject; // TipBar(막대) 오브젝트(부모일 수도 있음)
|
|||
|
|
|
|||
|
|
[Header("TipBar 실제 배경(선택)")]
|
|||
|
|
public RectTransform tipBarBackgroundRect;
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// 설정
|
|||
|
|
// =========================
|
|||
|
|
[Header("설정")]
|
|||
|
|
public string[] tips; // 랜덤으로 뽑을 팁 문구 배열
|
|||
|
|
public float fadeDuration = 1.0f; // 배경 페이드 속도(초)
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// TipBar 자동 리사이즈 설정
|
|||
|
|
// =========================
|
|||
|
|
[Header("TipBar 자동 리사이즈(코드)")]
|
|||
|
|
[Tooltip("Tip 텍스트 줄바꿈 기준 = 화면 폭의 몇 %를 쓸지")]
|
|||
|
|
[Range(0.4f, 0.95f)]
|
|||
|
|
public float wrapWidthScreenRatio = 0.75f;
|
|||
|
|
|
|||
|
|
[Tooltip("TipBar 안쪽 여백(좌/우 합, 상/하 합)")]
|
|||
|
|
public Vector2 tipPadding = new Vector2(120f, 60f);
|
|||
|
|
|
|||
|
|
[Tooltip("TipBar 최소 높이")]
|
|||
|
|
public float tipBarMinHeight = 70f;
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// 내부 캐시
|
|||
|
|
// =========================
|
|||
|
|
private RectTransform _tipBarRect;
|
|||
|
|
private RectTransform _tipTextRect;
|
|||
|
|
// private float _tipBarBaseHeight; // 사용하지 않는 변수이므로 삭제하여 경고 해결
|
|||
|
|
|
|||
|
|
[Header("TipBar 기본 높이(1줄 기준)")]
|
|||
|
|
public float tipBarBaseHeight = 220f;
|
|||
|
|
|
|||
|
|
private void Awake()
|
|||
|
|
{
|
|||
|
|
if (Instance == null)
|
|||
|
|
{
|
|||
|
|
Instance = this;
|
|||
|
|
DontDestroyOnLoad(gameObject);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Destroy(gameObject);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (loadingCanvas != null)
|
|||
|
|
loadingCanvas.SetActive(false);
|
|||
|
|
|
|||
|
|
if (tipText != null)
|
|||
|
|
_tipTextRect = tipText.GetComponent<RectTransform>();
|
|||
|
|
|
|||
|
|
if (tipBarBackgroundRect != null)
|
|||
|
|
_tipBarRect = tipBarBackgroundRect;
|
|||
|
|
else if (tipBarObject != null)
|
|||
|
|
_tipBarRect = tipBarObject.GetComponent<RectTransform>();
|
|||
|
|
|
|||
|
|
if (tipText != null)
|
|||
|
|
{
|
|||
|
|
tipText.enableWordWrapping = true;
|
|||
|
|
tipText.overflowMode = TextOverflowModes.Overflow;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void LoadSceneWithFade(string sceneName)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(LoadProcess(sceneName));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator LoadProcess(string sceneName)
|
|||
|
|
{
|
|||
|
|
if (loadingTextObject != null) loadingTextObject.SetActive(false);
|
|||
|
|
if (tipBarObject != null) tipBarObject.SetActive(false);
|
|||
|
|
|
|||
|
|
if (loadingCanvas != null) loadingCanvas.SetActive(true);
|
|||
|
|
if (backgroundGroup != null) backgroundGroup.alpha = 0f;
|
|||
|
|
|
|||
|
|
// ★ 수정됨: Fade 호출 시 backgroundGroup을 함께 전달
|
|||
|
|
yield return StartCoroutine(Fade(1f, backgroundGroup));
|
|||
|
|
|
|||
|
|
if (loadingTextObject != null) loadingTextObject.SetActive(true);
|
|||
|
|
if (tipBarObject != null) tipBarObject.SetActive(true);
|
|||
|
|
|
|||
|
|
if (tipText != null)
|
|||
|
|
{
|
|||
|
|
if (tips != null && tips.Length > 0)
|
|||
|
|
{
|
|||
|
|
int randomIndex = Random.Range(0, tips.Length);
|
|||
|
|
tipText.text = $"<color=#FFD700>Tip!</color> : {tips[randomIndex]}";
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
tipText.text = "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ResizeTipBarToFitText();
|
|||
|
|
yield return null;
|
|||
|
|
ResizeTipBarToFitText();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);
|
|||
|
|
op.allowSceneActivation = false;
|
|||
|
|
|
|||
|
|
float timer = 0f;
|
|||
|
|
while (timer < 2.0f)
|
|||
|
|
{
|
|||
|
|
timer += Time.deltaTime;
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
op.allowSceneActivation = true;
|
|||
|
|
|
|||
|
|
if (loadingTextObject != null) loadingTextObject.SetActive(false);
|
|||
|
|
if (tipBarObject != null) tipBarObject.SetActive(false);
|
|||
|
|
|
|||
|
|
// ★ 수정됨: Fade 호출 시 backgroundGroup을 함께 전달
|
|||
|
|
yield return StartCoroutine(Fade(0f, backgroundGroup));
|
|||
|
|
|
|||
|
|
if (loadingCanvas != null) loadingCanvas.SetActive(false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// =========================
|
|||
|
|
// 배경 페이드 함수 (안전 코드 적용)
|
|||
|
|
// =========================
|
|||
|
|
private IEnumerator Fade(float targetAlpha, CanvasGroup canvasGroup)
|
|||
|
|
{
|
|||
|
|
if (canvasGroup == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogWarning("SceneLoader: 페이드할 CanvasGroup이 없습니다!");
|
|||
|
|
yield break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// fadeDuration이 0인 경우 방지
|
|||
|
|
float duration = Mathf.Max(0.01f, fadeDuration);
|
|||
|
|
float speed = 1f / duration;
|
|||
|
|
|
|||
|
|
// null 체크 및 오차 범위 체크 추가
|
|||
|
|
while (canvasGroup != null && !Mathf.Approximately(canvasGroup.alpha, targetAlpha))
|
|||
|
|
{
|
|||
|
|
canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, targetAlpha, speed * Time.unscaledDeltaTime);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (canvasGroup != null)
|
|||
|
|
{
|
|||
|
|
canvasGroup.alpha = targetAlpha;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ResizeTipBarToFitText()
|
|||
|
|
{
|
|||
|
|
if (tipText == null || _tipBarRect == null || _tipTextRect == null) return;
|
|||
|
|
|
|||
|
|
float scale = 1f;
|
|||
|
|
var canvas = tipText.canvas;
|
|||
|
|
if (canvas != null) scale = canvas.scaleFactor;
|
|||
|
|
|
|||
|
|
float safeWrapWidth = (Screen.width * wrapWidthScreenRatio) / Mathf.Max(0.0001f, scale);
|
|||
|
|
safeWrapWidth = Mathf.Clamp(safeWrapWidth, 600f, 1400f);
|
|||
|
|
|
|||
|
|
float wrapWidth = Mathf.Max(200f, safeWrapWidth - tipPadding.x);
|
|||
|
|
|
|||
|
|
_tipTextRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, wrapWidth);
|
|||
|
|
|
|||
|
|
tipText.enableWordWrapping = true;
|
|||
|
|
tipText.overflowMode = TextOverflowModes.Overflow;
|
|||
|
|
tipText.ForceMeshUpdate();
|
|||
|
|
|
|||
|
|
Vector2 preferred = tipText.GetPreferredValues(tipText.text, wrapWidth, 0f);
|
|||
|
|
float textHeight = Mathf.Ceil(preferred.y);
|
|||
|
|
|
|||
|
|
_tipTextRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, textHeight);
|
|||
|
|
|
|||
|
|
float neededHeight = textHeight + tipPadding.y;
|
|||
|
|
float barHeight = Mathf.Max(tipBarBaseHeight, neededHeight, tipBarMinHeight);
|
|||
|
|
|
|||
|
|
_tipBarRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, barHeight);
|
|||
|
|
}
|
|||
|
|
}
|