250 lines
6.1 KiB
C#
250 lines
6.1 KiB
C#
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
|
||
}
|