yyl
2026-04-03 99a11d2bb19d74f6cc8584ac16838062af4fb301
Main/System/Battle/Sound/BattleSoundManager.cs
@@ -22,11 +22,17 @@
    // 记录每个音效ID当前播放的AudioSource
    private Dictionary<int, List<AudioSource>> audioIdToSources = new Dictionary<int, List<AudioSource>>();
    
    // 清理用缓存列表,避免每帧分配
    private List<int> _keysToRemoveCache = new List<int>();
    // 音频剪辑缓存
    private Dictionary<int, AudioClip> audioClipCache = new Dictionary<int, AudioClip>();
    
    // 当前播放速度
    private float currentSpeedRatio = 1f;
    // 跟踪AudioSource总数,避免GetComponents分配
    private int audioSourceCount = 0;
    
    // 是否有焦点
    private bool hasFocus = true;
@@ -111,6 +117,7 @@
            source.spatialBlend = 0f; // 2D音效
            audioSourcePool.Enqueue(source);
        }
        audioSourceCount = INITIAL_AUDIO_POOL;
        Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 初始化了 {INITIAL_AUDIO_POOL} 个 AudioSource</color>");
    }
    
@@ -145,21 +152,27 @@
        // 检查是否有焦点,无焦点时不播放
        if (!hasFocus)
        {
#if UNITY_EDITOR
            Debug.Log($"<color=yellow>BattleSoundManager [{battleField.guid}]: 无焦点,拒绝播放音效 {audioId}</color>");
#endif
            return;
        }
        
        // 检查该音效是否已达到播放上限
        if (!CanPlayAudio(audioId))
        {
#if UNITY_EDITOR
            Debug.Log($"<color=yellow>BattleSoundManager [{battleField.guid}]: 音效 {audioId} 达到播放上限,拒绝播放</color>");
#endif
            return;
        }
        
        var audioClip = await GetAudioClip(audioId);
        if (audioClip == null)
        {
#if UNITY_EDITOR
            Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: 无法加载音效 {audioId}</color>");
#endif
            return;
        }
        
@@ -167,7 +180,9 @@
        AudioSource source = GetAvailableAudioSource();
        if (source == null)
        {
#if UNITY_EDITOR
            Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: 无法获取AudioSource,池数量={audioSourcePool.Count},活跃数量={activeAudioSources.Count}</color>");
#endif
            return;
        }
        
@@ -190,7 +205,9 @@
        source.clip = audioClip;
        source.Play();
        
#if UNITY_EDITOR
        Debug.Log($"<color=green>BattleSoundManager [{battleField.guid}]: 播放音效 {audioId} - {audioClip.name}</color>");
#endif
        
        // 标记为活跃
        if (!activeAudioSources.Contains(source))
@@ -281,16 +298,18 @@
            {
                return source;
            }
#if UNITY_EDITOR
            Debug.Log($"<color=orange>BattleSoundManager [{battleField.guid}]: 池中的AudioSource已被销毁,跳过</color>");
#endif
        }
        
        // 计算当前总的 AudioSource 数量
        int totalAudioSources = audioSourceObject.GetComponents<AudioSource>().Length;
        if (totalAudioSources >= MAX_AUDIO_SOURCES)
        if (audioSourceCount >= MAX_AUDIO_SOURCES)
        {
            // 达到上限,不再创建,丢弃这次播放请求
#if UNITY_EDITOR
            Debug.Log($"BattleSoundManager: AudioSource 数量已达上限 {MAX_AUDIO_SOURCES},无法播放新音效");
#endif
            return null;
        }
        
@@ -299,8 +318,11 @@
        newSource.playOnAwake = false;
        newSource.loop = false;
        newSource.spatialBlend = 0f; // 2D音效
        audioSourceCount++;
        
        Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 动态创建新AudioSource,当前总数={totalAudioSources + 1}</color>");
#if UNITY_EDITOR
        Debug.Log($"<color=cyan>BattleSoundManager [{battleField.guid}]: 动态创建新AudioSource,当前总数={audioSourceCount}</color>");
#endif
        
        return newSource;
    }
@@ -328,18 +350,18 @@
        }
        
        // 清理 audioIdToSources 中已停止播放的 AudioSource
        var keysToRemove = new List<int>();
        _keysToRemoveCache.Clear();
        foreach (var kvp in audioIdToSources)
        {
            kvp.Value.RemoveAll(s => s == null || !s.isPlaying);
            if (kvp.Value.Count == 0)
            {
                keysToRemove.Add(kvp.Key);
                _keysToRemoveCache.Add(kvp.Key);
            }
        }
        
        // 移除空的音效ID记录
        foreach (var key in keysToRemove)
        foreach (var key in _keysToRemoveCache)
        {
            audioIdToSources.Remove(key);
        }
@@ -420,11 +442,15 @@
        int activeCount = activeAudioSources.Count;
        int totalStopped = 0;
        
        AudioSource[] allSources = null;
        // 不依赖列表,直接停止 GameObject 上的所有 AudioSource
        if (audioSourceObject != null)
        {
            var allSources = audioSourceObject.GetComponents<AudioSource>();
            allSources = audioSourceObject.GetComponents<AudioSource>();
#if UNITY_EDITOR
            Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - GameObject上共有 {allSources.Length} 个AudioSource</color>");
#endif
            
            foreach (var source in allSources)
            {
@@ -432,7 +458,9 @@
                {
                    if (source.isPlaying)
                    {
#if UNITY_EDITOR
                        Debug.Log($"<color=red>  停止正在播放的: {source.clip?.name}</color>");
#endif
                        totalStopped++;
                    }
                    source.Stop();
@@ -441,17 +469,18 @@
            }
        }
        
#if UNITY_EDITOR
        Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds - 活跃列表={activeCount}, 实际停止={totalStopped}</color>");
#endif
        
        // 清空所有列表
        activeAudioSources.Clear();
        audioIdToSources.Clear();
        
        // 重建对象池
        // 重建对象池(复用上面已获取的数组)
        audioSourcePool.Clear();
        if (audioSourceObject != null)
        if (allSources != null)
        {
            var allSources = audioSourceObject.GetComponents<AudioSource>();
            foreach (var source in allSources)
            {
                if (source != null)
@@ -461,7 +490,9 @@
            }
        }
        
#if UNITY_EDITOR
        Debug.Log($"<color=red>BattleSoundManager [{battleField.guid}]: StopAllSounds 完成</color>");
#endif
    }
    
    /// <summary>