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