195 lines
7.8 KiB
C#
195 lines
7.8 KiB
C#
using System.Collections;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UVC.UI.Loading
|
|
{
|
|
/// <summary>
|
|
/// 로딩 UI의 표시와 숨김, 진행 상태를 관리하는 클래스입니다.
|
|
/// CanvasGroup 컴포넌트를 사용하여 페이드 인/아웃 효과를 구현합니다.
|
|
/// 이 클래스가 게임 오브젝트에 추가되면 CanvasGroup 컴포넌트도 자동으로 추가됩니다.
|
|
/// </summary>
|
|
[RequireComponent(typeof(CanvasGroup))]
|
|
public class UILoadingBar : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// 로딩 바 UI 프리팹이 있는 Resources 폴더 내의 경로입니다.
|
|
/// Show() 메서드가 처음 호출될 때 이 경로를 사용하여 프리팹을 동적으로 생성합니다.
|
|
/// </summary>
|
|
public static string PrefabPath = "Prefabs/UI/Loading/UILoadingBar";
|
|
|
|
/// <summary>
|
|
/// UILoadingBar의 유일한 인스턴스(Singleton)입니다.
|
|
/// static으로 선언되어 어디서든 UILoadingBar.instance 형태로 접근할 수 있습니다.
|
|
/// </summary>
|
|
private static UILoadingBar instance;
|
|
|
|
/// <summary>
|
|
/// 로딩 진행률을 0.0에서 1.0 사이의 값으로 설정하거나 가져옵니다.
|
|
/// 이 값은 로딩 이미지의 채워지는 양(fillAmount)에 직접 반영됩니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <code>
|
|
/// // 로딩 진행률을 50%로 설정
|
|
/// UILoadingBar.Percent = 0.5f;
|
|
/// </code>
|
|
/// </example>
|
|
public static float Percent
|
|
{
|
|
get
|
|
{
|
|
if (instance == null) return 0;
|
|
return instance.loadinImage.fillAmount;
|
|
}
|
|
set
|
|
{
|
|
if (instance == null) return;
|
|
instance.loadinImage.fillAmount = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 로딩 화면에 표시될 메시지를 설정하거나 가져옵니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <code>
|
|
/// // 로딩 메시지 설정
|
|
/// UILoadingBar.Message = "데이터를 불러오는 중입니다...";
|
|
/// </code>
|
|
/// </example>
|
|
public static string Message
|
|
{
|
|
get
|
|
{
|
|
if (instance == null) return "";
|
|
return instance.text.text;
|
|
}
|
|
set
|
|
{
|
|
if (instance == null) return;
|
|
instance.text.text = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 로딩 바를 화면에 표시합니다.
|
|
/// 만약 로딩 바 인스턴스가 없다면 PrefabPath에서 프리팹을 불러와 생성합니다.
|
|
/// </summary>
|
|
/// <param name="message">로딩 화면에 표시할 메시지입니다.</param>
|
|
/// <example>
|
|
/// <code>
|
|
/// // 기본 메시지로 로딩 바 표시
|
|
/// UILoadingBar.Show();
|
|
///
|
|
/// // 특정 메시지와 함께 로딩 바 표시
|
|
/// UILoadingBar.Show("플레이어 정보를 로딩 중입니다...");
|
|
/// </code>
|
|
/// </example>
|
|
public static void Show(string message = "")
|
|
{
|
|
if (instance == null) {
|
|
GameObject prefab = Resources.Load<GameObject>(PrefabPath);
|
|
GameObject go = Instantiate(prefab);
|
|
go.name = "UILoadingBar";
|
|
go.transform.SetParent(null, false);
|
|
instance = go.GetComponent<UILoadingBar>();
|
|
}
|
|
Message = message;
|
|
instance.ShowLoading();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 로딩 바를 화면에서 숨깁니다.
|
|
/// 숨겨진 후에는 자동으로 파괴됩니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <code>
|
|
/// // 로딩 완료 후 로딩 바 숨기기
|
|
/// UILoadingBar.Hide();
|
|
/// </code>
|
|
/// </example>
|
|
public static void Hide()
|
|
{
|
|
if (instance != null)
|
|
{
|
|
instance.HideLoading();
|
|
}
|
|
}
|
|
|
|
[Tooltip("페이드 인/아웃 효과를 제어하는 CanvasGroup 컴포넌트입니다. 알파 값을 조정하여 UI의 투명도를 변경합니다.")]
|
|
[SerializeField]
|
|
private CanvasGroup canvasGroup; // 페이드 효과를 제어하기 위한 CanvasGroup 컴포넌트
|
|
[Tooltip("로딩 진행 상태를 표시하는 이미지 컴포넌트입니다. 로딩 중 진행률을 시각적으로 나타냅니다.")]
|
|
[SerializeField]
|
|
private Image loadinImage; // 로딩 진행 상태를 표시하는 이미지
|
|
[Tooltip("로딩 메시지를 표시하는 텍스트 컴포넌트입니다. 로딩 중 사용자에게 정보를 제공합니다.")]
|
|
[SerializeField]
|
|
private TextMeshProUGUI text; // 로딩 메시지를 표시하는 텍스트
|
|
private float target = 0; // 애니메이션의 목표 알파 값 (0: 투명, 1: 불투명)
|
|
private float duration = 0.25f; // 페이드 인/아웃 애니메이션 지속 시간
|
|
private bool animatting = false; // 현재 애니메이션이 진행 중인지 여부
|
|
|
|
/// <summary>
|
|
/// 로딩 바를 부드럽게 나타나게 하는 애니메이션을 시작합니다.
|
|
/// 이미 나타나는 중이면 다시 호출되지 않습니다.
|
|
/// </summary>
|
|
public void ShowLoading()
|
|
{
|
|
// 이미 애니메이션 중이고 목표 알파 값이 1(불투명)이면 중복 실행 방지
|
|
if (animatting && target == 1) return;
|
|
|
|
target = 1;
|
|
animatting = true;
|
|
StopCoroutine("Animate"); // 이전에 실행 중이던 Animate 코루틴이 있다면 중지
|
|
StartCoroutine(Animate()); // Animate 코루틴 시작
|
|
}
|
|
|
|
/// <summary>
|
|
/// 로딩 바를 부드럽게 사라지게 하는 애니메이션을 시작합니다.
|
|
/// 이미 사라지는 중이면 다시 호출되지 않습니다.
|
|
/// </summary>
|
|
public void HideLoading()
|
|
{
|
|
// 이미 애니메이션 중이고 목표 알파 값이 0(투명)이면 중복 실행 방지
|
|
if (animatting && target == 0) return;
|
|
|
|
target = 0;
|
|
animatting = true;
|
|
StopCoroutine("Animate"); // 이전에 실행 중이던 Animate 코루틴이 있다면 중지
|
|
StartCoroutine(Animate()); // Animate 코루틴 시작
|
|
}
|
|
|
|
/// <summary>
|
|
/// CanvasGroup의 알파 값을 조절하여 페이드 인/아웃 효과를 주는 코루틴입니다.
|
|
/// 코루틴은 특정 시간 동안 또는 특정 조건이 만족될 때까지 함수의 실행을 잠시 멈출 수 있는 특별한 함수입니다.
|
|
/// </summary>
|
|
private IEnumerator Animate()
|
|
{
|
|
float start = canvasGroup.alpha; // 애니메이션 시작 시점의 알파 값
|
|
float time = 0; // 애니메이션 경과 시간
|
|
|
|
// 경과 시간이 duration에 도달할 때까지 반복
|
|
while (time < duration)
|
|
{
|
|
time += Time.deltaTime; // 한 프레임 동안의 시간을 더해줌
|
|
// Mathf.Lerp를 사용하여 시작 알파 값과 목표 알파 값 사이를 부드럽게 보간
|
|
canvasGroup.alpha = Mathf.Lerp(start, target, time / duration);
|
|
// 다음 프레임까지 대기
|
|
yield return null;
|
|
}
|
|
|
|
// 애니메이션이 끝난 후 목표 알파 값으로 정확히 설정
|
|
canvasGroup.alpha = target;
|
|
animatting = false;
|
|
|
|
// 만약 목표 알파 값이 0(사라지는 애니메이션)이었다면, 게임 오브젝트를 파괴
|
|
if (target == 0)
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|