using TMPro; using UnityEngine; namespace AOT.UI { /// Local JSON-authored loading screen, available before CDN initialization. public sealed class BootPatchView : MonoBehaviour { TMP_Text _status, _percentage; RectTransform _fill; CanvasGroup _group; float _target, _shown; public static BootPatchView Create(BootPatchView prefab) { if (prefab == null) { Debug.LogError("[Boot] Loading prefab missing; run BuildBootLoading.Build before exporting."); return null; } var view = Instantiate(prefab); DontDestroyOnLoad(view.gameObject); return view; } void Awake() { _status = transform.Find("LoadingCard/Txt_Status").GetComponent(); _percentage = transform.Find("LoadingCard/Txt_Percentage").GetComponent(); _fill = transform.Find("LoadingCard/ProgressTrack/FillClip").GetComponent(); _group = GetComponent(); SetStatus("正在准备冒险…"); DrawProgress(); } void Update() { _shown = Mathf.MoveTowards(_shown, _target, Time.unscaledDeltaTime * .65f); DrawProgress(); } void DrawProgress() { if (_fill != null) _fill.anchorMax = new Vector2(_shown, 1f); if (_percentage != null) _percentage.text = Mathf.FloorToInt(_shown * 100f) + "%"; } public void SetStatus(string text) { if (_status != null) _status.text = text ?? string.Empty; } public void SetProgress(float normalized01) => _target = Mathf.Max(_target, Mathf.Clamp01(normalized01)); public void SetError(string message) { Debug.LogError("[Boot] " + message); SetStatus("加载失败,请重新进入游戏"); if (_status != null) _status.color = new Color(.72f, .22f, .18f); } public void Hide() => StartCoroutine(FadeOut()); System.Collections.IEnumerator FadeOut() { _shown = _target = 1f; DrawProgress(); yield return new WaitForSecondsRealtime(.12f); for (float time = 0; time < .25f; time += Time.unscaledDeltaTime) { if (_group != null) _group.alpha = 1f - time / .25f; yield return null; } gameObject.SetActive(false); } public void DestroyUi() => Destroy(gameObject); } }