using System.Collections; using UnityEngine; using BaseGames.Core.Events; namespace BaseGames.UI { /// /// 全屏黑幕渐入渐出遮罩(架构 10_UIModule §8)。 /// 由 SceneLoader 通过 EVT_LoadingOverlay BoolEventChannelSO 触发。 /// true = 淡入(遮挡场景),false = 淡出(显示场景)。 /// [RequireComponent(typeof(CanvasGroup))] public class LoadingOverlay : MonoBehaviour { [SerializeField] private CanvasGroup _canvasGroup; [SerializeField] private float _fadeDuration = 0.3f; [Header("Event Channel")] [SerializeField] private BoolEventChannelSO _onLoadingOverlayRequested; // EVT_LoadingOverlay private Coroutine _fadeCoroutine; private readonly CompositeDisposable _subs = new(); private void Awake() { if (_canvasGroup == null) _canvasGroup = GetComponent(); // 初始状态:完全透明,不阻挡射线 _canvasGroup.alpha = 0f; _canvasGroup.blocksRaycasts = false; } private void OnEnable() => _onLoadingOverlayRequested?.Subscribe(SetVisible).AddTo(_subs); private void OnDisable() => _subs.Clear(); public void SetVisible(bool visible) { if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine); _fadeCoroutine = StartCoroutine(FadeCoroutine(visible ? 1f : 0f)); } private IEnumerator FadeCoroutine(float target) { float start = _canvasGroup.alpha; float elapsed = 0f; // 遮挡时立刻阻挡射线,让开时完成后再放开 if (target > 0.5f) _canvasGroup.blocksRaycasts = true; while (elapsed < _fadeDuration) { _canvasGroup.alpha = Mathf.Lerp(start, target, elapsed / _fadeDuration); elapsed += Time.unscaledDeltaTime; yield return null; } _canvasGroup.alpha = target; _canvasGroup.blocksRaycasts = target > 0.5f; } } }