Files
Cielonos/Assets/Scripts/Core/UI/ScreenFader.cs
SoulliesOfficial 50ee502684 完善
2026-02-13 09:22:11 -05:00

103 lines
3.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using DG.Tweening; // 引入 DOTween
using UnityEngine;
using SLSUtilities.UI;
namespace Cielonos.Core.UI
{
// 继承 UIElementBase同时实现简单的单例逻辑
public class ScreenFader : UIElementBase
{
public static ScreenFader Instance { get; private set; }
[Header("Settings")]
[SerializeField] private float defaultDuration = 0.5f;
[SerializeField] private bool startBlack = true;
[SerializeField] private Ease fadeEase = Ease.InOutQuad; // 暴露曲线设置,比 SmoothStep 更灵活
private Tween currentTween; // 记录当前动画,防止冲突
private void Awake()
{
// --- 单例逻辑 ---
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
// ----------------
// 初始化状态
if (canvasGroup == null) canvasGroup = GetComponent<CanvasGroup>();
if (startBlack)
{
canvasGroup.alpha = 1f;
canvasGroup.blocksRaycasts = true;
}
else
{
canvasGroup.alpha = 0f;
canvasGroup.blocksRaycasts = false;
}
}
private void OnDestroy()
{
// 这是一个好习惯:销毁时杀掉所有未完成的动画,防止报错
currentTween?.Kill();
}
/// <summary>
/// 变黑 (Fade Out / 遮挡屏幕)
/// </summary>
public Tween FadeToBlack(float duration = -1, Action onComplete = null)
{
return FadeTo(1f, duration, onComplete);
}
/// <summary>
/// 变亮 (Fade In / 显示屏幕)
/// </summary>
public Tween FadeToClear(float duration = -1, float delay = 1, Action onComplete = null)
{
return FadeTo(0f, duration, onComplete).SetDelay(delay);
}
/// <summary>
/// 通用淡入淡出逻辑
/// 返回 Tween 对象,允许外部使用 yield return tween.WaitForCompletion();
/// </summary>
private Tween FadeTo(float targetAlpha, float duration, Action onComplete)
{
// 1. 如果有正在运行的动画,立刻杀掉,确保从当前 alpha 开始新的变化
currentTween?.Kill();
float d = duration < 0 ? defaultDuration : duration;
// 2. 只有在变黑alpha -> 1开始时才阻挡射线
// 这样防止玩家在变黑过程中还能点击后面的按钮
if (targetAlpha > 0.5f)
{
canvasGroup.blocksRaycasts = true;
}
// 3. 使用 DOTween
currentTween = canvasGroup.DOFade(targetAlpha, d)
.SetEase(fadeEase)
.SetUpdate(true) // 【关键】忽略 TimeScale游戏暂停时依然可以淡入淡出
.OnComplete(() =>
{
// 只有在完全变亮alpha -> 0结束后才取消阻挡
if (targetAlpha < 0.01f)
{
canvasGroup.blocksRaycasts = false;
}
onComplete?.Invoke();
});
return currentTween;
}
}
}