Files
zeling_v2/Assets/_Game/Scripts/UI/LoadingScreenManager.cs
2026-05-25 13:21:41 +08:00

95 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using BaseGames.Core.Events;
using BaseGames.Localization;
namespace BaseGames.UI
{
/// <summary>
/// 全屏加载界面:进度条 + 提示文字 + 随机背景图(架构 10_UIModule §7.7)。
/// </summary>
public class LoadingScreenManager : MonoBehaviour
{
[SerializeField] private GameObject _loadingRoot;
[SerializeField] private Image _progressFill;
[SerializeField] private TMP_Text _tipText;
[SerializeField] private Image[] _backgroundArts;
[SerializeField] private string[] _tipMessages; // 本地化 key对应 "UI" 表中的条目,如 "tip_explore"
[SerializeField] private float _minDisplayTime = 0.5f;
[Header("Event Channels")]
[SerializeField] private VoidEventChannelSO _onLoadingStarted;
[SerializeField] private VoidEventChannelSO _onLoadingComplete;
[SerializeField] private FloatEventChannelSO _onLoadingProgressUpdated;
private float _shownAt;
private readonly CompositeDisposable _subs = new();
private void OnEnable()
{
_onLoadingStarted?.Subscribe(Show).AddTo(_subs);
_onLoadingComplete?.Subscribe(Hide).AddTo(_subs);
_onLoadingProgressUpdated?.Subscribe(SetProgress).AddTo(_subs);
}
private void OnDisable()
{
_subs.Clear();
}
// ── 公开 APISceneLoader 可直接调用)────────────────────────────────
public void Show()
{
_shownAt = Time.unscaledTime;
if (_loadingRoot != null) _loadingRoot.SetActive(true);
if (_progressFill != null) _progressFill.fillAmount = 0f;
// 随机背景
if (_backgroundArts != null && _backgroundArts.Length > 0)
{
foreach (var bg in _backgroundArts) if (bg != null) bg.enabled = false;
_backgroundArts[Random.Range(0, _backgroundArts.Length)].enabled = true;
}
// 随机提示(通过 LocalizationManager 解析 key
if (_tipText != null && _tipMessages != null && _tipMessages.Length > 0)
_tipText.text = LocalizationManager.Get(_tipMessages[Random.Range(0, _tipMessages.Length)], LocalizationTable.UI);
}
public void Hide() => StartCoroutine(HideAfterMinTime());
public void SetProgress(float value)
{
if (_progressFill != null)
_progressFill.fillAmount = Mathf.Clamp01(value);
}
// ── 内部 ─────────────────────────────────────────────────────────────
// 缓存等待对象以避免典型路径(剩余时间 == _minDisplayTime下的重复分配。
private WaitForSecondsRealtime _cachedFullWait;
private IEnumerator HideAfterMinTime()
{
float elapsed = Time.unscaledTime - _shownAt;
float remaining = _minDisplayTime - elapsed;
if (remaining > 0f)
{
// 完整剩余 ≈ 显示时间时复用缓存对象;否则按需新建(罕见路径)。
if (Mathf.Approximately(remaining, _minDisplayTime))
{
_cachedFullWait ??= new WaitForSecondsRealtime(_minDisplayTime);
yield return _cachedFullWait;
}
else
{
yield return new WaitForSecondsRealtime(remaining);
}
}
if (_loadingRoot != null) _loadingRoot.SetActive(false);
}
}
}