| | |
| | | using UnityEngine; |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | |
| | | /// <summary> |
| | |
| | | public BattleSoundManager(BattleField _battleField) |
| | | { |
| | | battleField = _battleField; |
| | | BattleDebug.LogError($"<color=cyan>BattleSoundManager [{battleField.guid}]: 构造函数 - 初始焦点状态={battleField.IsFocus()}</color>"); |
| | | Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 构造函数 - 初始焦点状态={battleField.IsFocus()}</color>"); |
| | | InitializeAudioSources(); |
| | | |
| | | // 监听战场速度变化 |
| | |
| | | { |
| | | if (pauseState == UnityEditor.PauseState.Paused) |
| | | { |
| | | BattleDebug.LogError($"<color=yellow>BattleSoundManager [{battleField.guid}]: 编辑器暂停,停止所有音效</color>"); |
| | | Debug.Log($"<color=yellow>BattleSoundManager [{battleField.guid}]: 编辑器暂停,停止所有音效</color>"); |
| | | for (int i = activeAudioSources.Count - 1; i >= 0; i--) |
| | | { |
| | | var source = activeAudioSources[i]; |
| | |
| | | } |
| | | else if (pauseState == UnityEditor.PauseState.Unpaused) |
| | | { |
| | | BattleDebug.LogError($"<color=green>BattleSoundManager [{battleField.guid}]: 编辑器恢复</color>"); |
| | | Debug.Log($"<color=green>BattleSoundManager [{battleField.guid}]: 编辑器恢复</color>"); |
| | | for (int i = activeAudioSources.Count - 1; i >= 0; i--) |
| | | { |
| | | var source = activeAudioSources[i]; |
| | |
| | | source.spatialBlend = 0f; // 2D音效 |
| | | audioSourcePool.Enqueue(source); |
| | | } |
| | | BattleDebug.LogError($"<color=cyan>BattleSoundManager [{battleField.guid}]: 初始化了 {INITIAL_AUDIO_POOL} 个 AudioSource</color>"); |
| | | Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 初始化了 {INITIAL_AUDIO_POOL} 个 AudioSource</color>"); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | // 检查是否有焦点,无焦点时不播放 |
| | | if (!hasFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=yellow>BattleSoundManager [{battleField.guid}]: 无焦点,拒绝播放音效 {audioId}</color>"); |
| | | Debug.Log($"<color=yellow>BattleSoundManager [{battleField.guid}]: 无焦点,拒绝播放音效 {audioId}</color>"); |
| | | return; |
| | | } |
| | | |
| | | // 检查该音效是否已达到播放上限 |
| | | if (!CanPlayAudio(audioId)) |
| | | { |
| | | Debug.Log($"<color=yellow>BattleSoundManager [{battleField.guid}]: 音效 {audioId} 达到播放上限,拒绝播放</color>"); |
| | | return; |
| | | } |
| | | |
| | | var audioClip = GetAudioClip(audioId); |
| | | if (audioClip == null) |
| | | { |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: 无法加载音效 {audioId}</color>"); |
| | | return; |
| | | } |
| | | |
| | |
| | | AudioSource source = GetAvailableAudioSource(); |
| | | if (source == null) |
| | | { |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: 无法获取AudioSource,池数量={audioSourcePool.Count},活跃数量={activeAudioSources.Count}</color>"); |
| | | return; |
| | | } |
| | | |
| | |
| | | source.clip = audioClip; |
| | | source.Play(); |
| | | |
| | | BattleDebug.LogError($"<color=green>BattleSoundManager [{battleField.guid}]: 播放音效 {audioId} - {audioClip.name}</color>"); |
| | | Debug.Log($"<color=green>BattleSoundManager [{battleField.guid}]: 播放音效 {audioId} - {audioClip.name}</color>"); |
| | | |
| | | // 标记为活跃 |
| | | if (!activeAudioSources.Contains(source)) |
| | |
| | | /// </summary> |
| | | private AudioSource GetAvailableAudioSource() |
| | | { |
| | | // 尝试从池中获取 |
| | | if (audioSourcePool.Count > 0) |
| | | // 检查 audioSourceObject 是否仍然有效(Unity 对象可能被销毁但引用不为 null) |
| | | if (audioSourceObject == null || !audioSourceObject) |
| | | { |
| | | return audioSourcePool.Dequeue(); |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: audioSourceObject 已被销毁或无效!尝试重新获取</color>"); |
| | | // 尝试重新获取 |
| | | if (battleField != null && battleField.battleRootNode != null) |
| | | { |
| | | audioSourceObject = battleField.battleRootNode.gameObject; |
| | | Debug.Log($"<color=green>BattleSoundManager [{battleField.guid}]: 重新获取 audioSourceObject 成功</color>"); |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("BattleSoundManager: 无法重新获取 audioSourceObject"); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // 如果池为空,检查是否可以动态创建 |
| | | if (audioSourceObject == null) |
| | | // 尝试从池中获取 |
| | | while (audioSourcePool.Count > 0) |
| | | { |
| | | BattleDebug.LogError("BattleSoundManager: audioSourceObject 为空,无法创建 AudioSource"); |
| | | return null; |
| | | var source = audioSourcePool.Dequeue(); |
| | | // 检查 AudioSource 是否仍然有效(真机上可能被销毁) |
| | | if (source != null) |
| | | { |
| | | return source; |
| | | } |
| | | Debug.Log($"<color=orange>BattleSoundManager [{battleField.guid}]: 池中的AudioSource已被销毁,跳过</color>"); |
| | | } |
| | | |
| | | // 计算当前总的 AudioSource 数量 |
| | |
| | | if (totalAudioSources >= MAX_AUDIO_SOURCES) |
| | | { |
| | | // 达到上限,不再创建,丢弃这次播放请求 |
| | | BattleDebug.LogError($"BattleSoundManager: AudioSource 数量已达上限 {MAX_AUDIO_SOURCES},无法播放新音效"); |
| | | Debug.Log($"BattleSoundManager: AudioSource 数量已达上限 {MAX_AUDIO_SOURCES},无法播放新音效"); |
| | | return null; |
| | | } |
| | | |
| | | // 在 battleRootNode 上动态创建新的 AudioSource |
| | | var source = audioSourceObject.AddComponent<AudioSource>(); |
| | | source.playOnAwake = false; |
| | | source.loop = false; |
| | | source.spatialBlend = 0f; // 2D音效 |
| | | var newSource = audioSourceObject.AddComponent<AudioSource>(); |
| | | newSource.playOnAwake = false; |
| | | newSource.loop = false; |
| | | newSource.spatialBlend = 0f; // 2D音效 |
| | | |
| | | return source; |
| | | Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 动态创建新AudioSource,当前总数={totalAudioSources + 1}</color>"); |
| | | |
| | | return newSource; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | private void OnFocusChanged(bool isFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=magenta>BattleSoundManager [{battleField.guid}]: OnFocusChanged({isFocus}) - 当前活跃音效数={activeAudioSources.Count}</color>"); |
| | | Debug.Log($"<color=magenta>BattleSoundManager [{battleField.guid}]: OnFocusChanged({isFocus}) - 当前活跃音效数={activeAudioSources.Count}</color>"); |
| | | |
| | | hasFocus = isFocus; |
| | | |
| | | // 失去焦点时,停止所有正在播放的音效 |
| | | if (!hasFocus) |
| | | { |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: 失去焦点,准备停止所有音效</color>"); |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: 失去焦点,准备停止所有音效</color>"); |
| | | StopAllSounds(); |
| | | } |
| | | else |
| | | { |
| | | BattleDebug.LogError($"<color=green>BattleSoundManager [{battleField.guid}]: 获得焦点</color>"); |
| | | Debug.Log($"<color=green>BattleSoundManager [{battleField.guid}]: 获得焦点</color>"); |
| | | } |
| | | } |
| | | |
| | |
| | | if (audioSourceObject != null) |
| | | { |
| | | var allSources = audioSourceObject.GetComponents<AudioSource>(); |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - GameObject上共有 {allSources.Length} 个AudioSource</color>"); |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - GameObject上共有 {allSources.Length} 个AudioSource</color>"); |
| | | |
| | | foreach (var source in allSources) |
| | | { |
| | |
| | | { |
| | | if (source.isPlaying) |
| | | { |
| | | BattleDebug.LogError($"<color=red> 停止正在播放的: {source.clip?.name}</color>"); |
| | | Debug.Log($"<color=red> 停止正在播放的: {source.clip?.name}</color>"); |
| | | totalStopped++; |
| | | } |
| | | source.Stop(); |
| | |
| | | } |
| | | } |
| | | |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - 活跃列表={activeCount}, 实际停止={totalStopped}</color>"); |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - 活跃列表={activeCount}, 实际停止={totalStopped}</color>"); |
| | | |
| | | // 清空所有列表 |
| | | activeAudioSources.Clear(); |
| | |
| | | } |
| | | } |
| | | |
| | | BattleDebug.LogError($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds 完成</color>"); |
| | | Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds 完成</color>"); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | public void Release() |
| | | { |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 开始</color>"); |
| | | Debug.Log($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 开始</color>"); |
| | | |
| | | if (battleField != null) |
| | | { |
| | |
| | | if (audioSourceObject != null) |
| | | { |
| | | var sources = audioSourceObject.GetComponents<AudioSource>(); |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: 销毁 {sources.Length} 个 AudioSource 组件</color>"); |
| | | Debug.Log($"<color=orange>BattleSoundManager [{battleField.guid}]: 销毁 {sources.Length} 个 AudioSource 组件</color>"); |
| | | foreach (var source in sources) |
| | | { |
| | | if (source != null) |
| | |
| | | audioIdToSources.Clear(); |
| | | audioClipCache.Clear(); |
| | | |
| | | BattleDebug.LogError($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 完成</color>"); |
| | | Debug.Log($"<color=orange>BattleSoundManager [{battleField.guid}]: Release 完成</color>"); |
| | | } |
| | | } |
| | | } |