61 lines
2.1 KiB
C#
61 lines
2.1 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
using BaseGames.Core.Events;
|
||
|
||
namespace BaseGames.UI
|
||
{
|
||
/// <summary>
|
||
/// 全屏黑幕渐入渐出遮罩(架构 10_UIModule §8)。
|
||
/// 由 SceneLoader 通过 EVT_LoadingOverlay BoolEventChannelSO 触发。
|
||
/// true = 淡入(遮挡场景),false = 淡出(显示场景)。
|
||
/// </summary>
|
||
[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>();
|
||
// 初始状态:完全透明,不阻挡射线
|
||
_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;
|
||
}
|
||
}
|
||
}
|