using System.Collections; using UnityEngine; using BaseGames.Core.Events; namespace BaseGames.UI { /// /// 右下角存档进行中提示(架构 10_UIModule §7.6)。 /// 订阅 EVT_SaveIndicatorVisible(BoolEventChannelSO):true = 淡入,false = 淡出。 /// [RequireComponent(typeof(CanvasGroup))] public class SaveIndicator : MonoBehaviour { [SerializeField] private CanvasGroup _cg; [SerializeField] private float _fadeDuration = 0.2f; [Header("Event Channel")] [SerializeField] private BoolEventChannelSO _onSaveIndicatorVisible; // EVT_SaveIndicatorVisible private Coroutine _fadeCoroutine; private readonly CompositeDisposable _subs = new(); private void Awake() { if (_cg == null) _cg = GetComponent(); _cg.alpha = 0f; } private void OnEnable() { _onSaveIndicatorVisible?.Subscribe(OnVisibilityChanged).AddTo(_subs); } private void OnDisable() { _subs.Clear(); } private void OnVisibilityChanged(bool visible) => FadeTo(visible ? 1f : 0f); private void FadeTo(float target) { if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine); _fadeCoroutine = StartCoroutine(FadeCoroutine(target)); } private IEnumerator FadeCoroutine(float target) { float start = _cg.alpha; float elapsed = 0f; while (elapsed < _fadeDuration) { _cg.alpha = Mathf.Lerp(start, target, elapsed / _fadeDuration); elapsed += Time.unscaledDeltaTime; yield return null; } _cg.alpha = target; } } }