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
|
|||
|
|
}
|