using System.Collections; using UnityEngine; using UnityEngine.UI; using TMPro; using BaseGames.Core.Events; using BaseGames.Localization; namespace BaseGames.UI { /// /// 全屏加载界面:进度条 + 提示文字 + 随机背景图(架构 10_UIModule §7.7)。 /// 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(); } // ── 公开 API(SceneLoader 可直接调用)──────────────────────────────── 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)], "UI"); } public void Hide() => StartCoroutine(HideAfterMinTime()); public void SetProgress(float value) { if (_progressFill != null) _progressFill.fillAmount = Mathf.Clamp01(value); } // ── 内部 ───────────────────────────────────────────────────────────── private IEnumerator HideAfterMinTime() { float elapsed = Time.unscaledTime - _shownAt; if (elapsed < _minDisplayTime) yield return new WaitForSecondsRealtime(_minDisplayTime - elapsed); if (_loadingRoot != null) _loadingRoot.SetActive(false); } } }