NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Audio/AudioFadeEffect.cs

250 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using UnityEngine;
/// <summary>
/// 音频淡入淡出效果类(简化版)
/// 职责:管理音频的淡入淡出效果,与播放逻辑解耦
/// 设计:使用状态机模式,单一计时器,逻辑清晰
/// </summary>
public class AudioFadeEffect
{
#region Enums
/// <summary>
/// 淡入淡出状态
/// </summary>
public enum FadeState
{
None, // 无效果
FadingIn, // 正在淡入
FadingOut, // 正在淡出
}
#endregion
#region Fields
private FadeState _state = FadeState.None;
private float _elapsedTime = 0f; // 当前状态经过的时间
private float _fadeInDuration = 4f; // 淡入时长(秒)
private float _fadeOutDuration = 4f; // 淡出时长(秒)
#endregion
#region Properties
/// <summary>
/// 当前淡入淡出系数 (0-1)
/// </summary>
public float FadeValue { get; private set; } = 1f;
/// <summary>
/// 当前状态
/// </summary>
public FadeState State => _state;
/// <summary>
/// 是否正在淡入
/// </summary>
public bool IsFadingIn => _state == FadeState.FadingIn;
/// <summary>
/// 是否正在淡出
/// </summary>
public bool IsFadingOut => _state == FadeState.FadingOut;
/// <summary>
/// 是否有任何效果激活
/// </summary>
public bool IsActive => _state != FadeState.None;
/// <summary>
/// 淡入时长(秒)
/// </summary>
public float FadeInDuration
{
get => _fadeInDuration;
set => _fadeInDuration = Mathf.Max(0.01f, value);
}
/// <summary>
/// 淡出时长(秒)
/// </summary>
public float FadeOutDuration
{
get => _fadeOutDuration;
set => _fadeOutDuration = Mathf.Max(0.01f, value);
}
#endregion
#region Constructor
/// <summary>
/// 创建淡入淡出效果
/// </summary>
/// <param name="fadeInDuration">淡入时长(秒)</param>
/// <param name="fadeOutDuration">淡出时长(秒)</param>
public AudioFadeEffect(float fadeInDuration = 4f, float fadeOutDuration = 4f)
{
_fadeInDuration = Mathf.Max(0.01f, fadeInDuration);
_fadeOutDuration = Mathf.Max(0.01f, fadeOutDuration);
FadeValue = 1f;
}
#endregion
#region Public Methods
/// <summary>
/// 开始淡入效果
/// </summary>
/// <param name="duration">淡入时长null 则使用默认值</param>
public void StartFadeIn(float? duration = null)
{
if (duration.HasValue)
{
_fadeInDuration = Mathf.Max(0.01f, duration.Value);
}
_state = FadeState.FadingIn;
_elapsedTime = 0f;
FadeValue = 0f;
}
/// <summary>
/// 开始淡出效果
/// </summary>
/// <param name="duration">淡出时长null 则使用默认值</param>
/// <returns>如果已经在淡出中则返回 false</returns>
public bool StartFadeOut(float? duration = null)
{
if (_state == FadeState.FadingOut)
return false;
if (duration.HasValue)
{
_fadeOutDuration = Mathf.Max(0.01f, duration.Value);
}
_state = FadeState.FadingOut;
_elapsedTime = 0f;
// FadeValue 保持当前值,从当前音量开始淡出
return true;
}
/// <summary>
/// 停止所有淡入淡出效果
/// </summary>
public void Stop()
{
_state = FadeState.None;
_elapsedTime = 0f;
FadeValue = 1f;
}
/// <summary>
/// 重置到初始状态(无淡入淡出)
/// </summary>
public void Reset()
{
Stop();
}
/// <summary>
/// 更新淡入淡出效果
/// </summary>
/// <param name="deltaTime">时间增量</param>
/// <returns>是否应该停止播放(淡出完成)</returns>
public bool Update(float deltaTime)
{
if (_state == FadeState.None)
{
FadeValue = 1f;
return false;
}
_elapsedTime += deltaTime;
switch (_state)
{
case FadeState.FadingIn:
return UpdateFadeIn();
case FadeState.FadingOut:
return UpdateFadeOut();
default:
return false;
}
}
/// <summary>
/// 获取当前应用淡入淡出后的音量
/// </summary>
/// <param name="originalVolume">原始音量</param>
/// <returns>应用淡入淡出系数后的音量</returns>
public float ApplyFade(float originalVolume)
{
return originalVolume * FadeValue;
}
#endregion
#region Private Methods
/// <summary>
/// 更新淡入
/// </summary>
private bool UpdateFadeIn()
{
if (_elapsedTime >= _fadeInDuration)
{
// 淡入完成
FadeValue = 1f;
_state = FadeState.None;
return false;
}
// 计算淡入进度
FadeValue = Mathf.Clamp01(_elapsedTime / _fadeInDuration);
return false;
}
/// <summary>
/// 更新淡出
/// </summary>
private bool UpdateFadeOut()
{
if (_elapsedTime >= _fadeOutDuration)
{
// 淡出完成
FadeValue = 0f;
_state = FadeState.None;
return true; // 通知调用者应该停止播放
}
// 计算淡出进度从当前值淡出到0
float progress = _elapsedTime / _fadeOutDuration;
FadeValue = Mathf.Lerp(FadeValue, 0f, progress);
return false;
}
#endregion
#region Debug
/// <summary>
/// 获取调试信息
/// </summary>
public string GetDebugInfo()
{
return $"FadeEffect: State={_state}, Value={FadeValue:F2}, " +
$"Elapsed={_elapsedTime:F2}s, " +
$"Durations(In={_fadeInDuration:F1}s, Out={_fadeOutDuration:F1}s)";
}
#endregion
}