| | |
| | | public BattleSoundManager(BattleField _battleField) |
| | | { |
| | | battleField = _battleField; |
| | | BattleDebug.LogError($"<color=cyan>BattleSoundManager [{battleField.guid}]: 构造函数 - 初始焦点状态={battleField.IsFocus()}</color>"); |
| | | InitializeAudioSources(); |
| | | |
| | | // 监听战场速度变化 |
| | | if (battleField != null) |
| | | { |
| | | battleField.OnSpeedRatioChange -= OnSpeedRatioChanged; |
| | | battleField.OnSpeedRatioChange += OnSpeedRatioChanged; |
| | | battleField.OnFocusChange -= OnFocusChanged; |
| | | battleField.OnFocusChange += OnFocusChanged; |
| | | currentSpeedRatio = battleField.speedRatio; |
| | | hasFocus = battleField.IsFocus(); |
| | |
| | | source.spatialBlend = 0f; // 2D音效 |
| | | audioSourcePool.Enqueue(source); |
| | | } |
| | | BattleDebug.LogError($"<color=cyan>BattleSoundManager [{battleField.guid}]: 初始化了 {INITIAL_AUDIO_POOL} 个 AudioSource</color>"); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | // 检查是否有焦点,无焦点时不播放 |
| | | if (!hasFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=yellow>BattleSoundManager [{battleField.guid}]: 无焦点,拒绝播放音效 {audioId}</color>"); |
| | | return; |
| | | } |
| | | |
| | |
| | | // 设置音频剪辑并播放(使用 Play() 而不是 PlayOneShot(),以便 isPlaying 状态正确) |
| | | source.clip = audioClip; |
| | | source.Play(); |
| | | |
| | | BattleDebug.LogError($"<color=green>BattleSoundManager [{battleField.guid}]: 播放音效 {audioId} - {audioClip.name}</color>"); |
| | | |
| | | // 标记为活跃 |
| | | if (!activeAudioSources.Contains(source)) |
| | |
| | | // 如果池为空,检查是否可以动态创建 |
| | | if (audioSourceObject == null) |
| | | { |
| | | Debug.LogError("BattleSoundManager: audioSourceObject 为空,无法创建 AudioSource"); |
| | | BattleDebug.LogErrorError("BattleSoundManager: audioSourceObject 为空,无法创建 AudioSource"); |
| | | return null; |
| | | } |
| | | |
| | |
| | | if (totalAudioSources >= MAX_AUDIO_SOURCES) |
| | | { |
| | | // 达到上限,不再创建,丢弃这次播放请求 |
| | | Debug.LogWarning($"BattleSoundManager: AudioSource 数量已达上限 {MAX_AUDIO_SOURCES},无法播放新音效"); |
| | | BattleDebug.LogErrorWarning($"BattleSoundManager: AudioSource 数量已达上限 {MAX_AUDIO_SOURCES},无法播放新音效"); |
| | | return null; |
| | | } |
| | | |
| | |
| | | if (source != null) |
| | | { |
| | | // 清空 clip 引用,释放内存 |
| | | source.Stop(); |
| | | source.clip = null; |
| | | audioSourcePool.Enqueue(source); |
| | | } |
| | |
| | | /// </summary> |
| | | private void OnFocusChanged(bool isFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=magenta>BattleSoundManager [{battleField.guid}]: OnFocusChanged({isFocus}) - 当前活跃音效数={activeAudioSources.Count}</color>"); |
| | | |
| | | hasFocus = isFocus; |
| | | |
| | | // 失去焦点时,停止所有正在播放的音效 |
| | | if (!hasFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: 失去焦点,准备停止所有音效</color>"); |
| | | StopAllSounds(); |
| | | } |
| | | else |
| | | { |
| | | BattleDebug.LogError($"<color=green>BattleSoundManager [{battleField.guid}]: 获得焦点</color>"); |
| | | } |
| | | } |
| | | |
| | |
| | | /// </summary> |
| | | public void StopAllSounds() |
| | | { |
| | | foreach (var source in activeAudioSources) |
| | | int activeCount = activeAudioSources.Count; |
| | | int totalStopped = 0; |
| | | |
| | | // 不依赖列表,直接停止 GameObject 上的所有 AudioSource |
| | | if (audioSourceObject != null) |
| | | { |
| | | if (source != null && source.isPlaying) |
| | | var allSources = audioSourceObject.GetComponents<AudioSource>(); |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - GameObject上共有 {allSources.Length} 个AudioSource</color>"); |
| | | |
| | | foreach (var source in allSources) |
| | | { |
| | | source.Stop(); |
| | | if (source != null) |
| | | { |
| | | if (source.isPlaying) |
| | | { |
| | | BattleDebug.LogError($"<color=red> 停止正在播放的: {source.clip?.name}</color>"); |
| | | totalStopped++; |
| | | } |
| | | source.Stop(); |
| | | source.clip = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 清理并回收所有音频源 |
| | | foreach (var source in activeAudioSources) |
| | | { |
| | | if (source != null) |
| | | { |
| | | // 清空 clip 引用 |
| | | source.clip = null; |
| | | audioSourcePool.Enqueue(source); |
| | | } |
| | | } |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - 活跃列表={activeCount}, 实际停止={totalStopped}</color>"); |
| | | |
| | | // 清空所有列表 |
| | | activeAudioSources.Clear(); |
| | | audioIdToSources.Clear(); |
| | | |
| | | // 重建对象池 |
| | | audioSourcePool.Clear(); |
| | | if (audioSourceObject != null) |
| | | { |
| | | var allSources = audioSourceObject.GetComponents<AudioSource>(); |
| | | foreach (var source in allSources) |
| | | { |
| | | if (source != null) |
| | | { |
| | | audioSourcePool.Enqueue(source); |
| | | } |
| | | } |
| | | } |
| | | |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds 完成</color>"); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | public void Release() |
| | | { |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 开始</color>"); |
| | | |
| | | if (battleField != null) |
| | | { |
| | | battleField.OnSpeedRatioChange -= OnSpeedRatioChanged; |
| | |
| | | if (audioSourceObject != null) |
| | | { |
| | | var sources = audioSourceObject.GetComponents<AudioSource>(); |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: 销毁 {sources.Length} 个 AudioSource 组件</color>"); |
| | | foreach (var source in sources) |
| | | { |
| | | if (source != null) |
| | |
| | | activeAudioSources.Clear(); |
| | | audioIdToSources.Clear(); |
| | | audioClipCache.Clear(); |
| | | |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 完成</color>"); |
| | | } |
| | | } |