Files
plugin-library/Assets/04.AudioCore/RunTime/AudioSourcePool.cs
2025-03-06 17:24:31 +08:00

136 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
public class AudioSourcePool
{
// 对象池字典,存储类型和对应的 GameObject 队列
private Dictionary<string, Queue<GameObject>> poolDict = new Dictionary<string, Queue<GameObject>>();
private GameObject poolObject;
/// <summary>
/// 对象池初始化
/// </summary>
private void PoolAwake()
{
// 检查是否已经存在一个名为"AudioSourcePool"的对象
SceneManager.sceneUnloaded += OnSceneUnloaded;
poolObject = GameObject.Find("AudioSourcePool");
if (poolObject == null)
{
// 如果不存在,创建一个新对象
poolObject = new GameObject("AudioSourcePool");
}
CoroutineHelper.SetRunner();
// 初始化 Voice 池(最多 1 个)
poolDict["Voice"] = new Queue<GameObject>();
CreateAudioSource("Voice");
// 初始化 Music 池(最多 2 个)
poolDict["Music"] = new Queue<GameObject>();
for (int i = 0; i < 2; i++)
{
CreateAudioSource("Music");
}
// 初始化 SFX 池(初始 4 个,可动态扩展)
poolDict["SFX"] = new Queue<GameObject>();
for (int i = 0; i < 4; i++)
{
CreateAudioSource("SFX");
}
}
/// <summary>
/// 创建对象
/// </summary>
/// <param name="type">定义对象类型</param>
private void CreateAudioSource(string type)
{
GameObject newObject = new GameObject($"AudioSource_{type}");
newObject.transform.SetParent(poolObject.transform); // 将新对象作为当前对象的子对象
newObject.AddComponent<AudioSource>().playOnAwake = false; // 添加 AudioSource 组件并禁用自动播放
poolDict[type].Enqueue(newObject);
}
/// <summary>
/// 获取对象
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public AudioSource GetAudioSource(string type)
{
if(poolObject == null)
{
PoolAwake();
}
if (!poolDict.ContainsKey(type))
{
Debug.LogError($"对象池中不存在类型: {type}");
return null;
}
if (poolDict[type].Count == 0)
{
/*// 如果池为空,动态创建新的 GameObject仅限 SFX
if (type == "SFX")
{
CreateAudioSource(type);
}
else
{
Debug.LogWarning($"对象池 {type} 已用完,无法分配新的 AudioSource");
return null;
}*/
CreateAudioSource(type);
}
GameObject audioObject = poolDict[type].Dequeue();
AudioSource audioSource = audioObject.GetComponent<AudioSource>();
return audioSource;
}
/// <summary>
/// 回收对象
/// </summary>
/// <param name="type"></param>
/// <param name="audioObject"></param>
public void ReturnAudioSource(string type, GameObject audioObject)
{
if (!poolDict.ContainsKey(type))
{
Debug.LogError($"对象池中不存在类型: {type}");
return;
}
AudioSource audioSource = audioObject.GetComponent<AudioSource>();
audioSource.Stop(); // 停止播放
audioSource.clip = null; // 清空音频剪辑
audioSource.volume = 1f; // 音量大小恢复
poolDict[type].Enqueue(audioObject); // 回收到对象池
}
/// <summary>
/// 场景销毁时清空对象池
/// </summary>
/// <param name="scene"></param>
void OnSceneUnloaded(Scene scene)
{
foreach (var pair in poolDict)
{
Queue<GameObject> queue = pair.Value;
while (queue.Count > 0)
{
GameObject obj = queue.Dequeue();
if(obj != null)
{
UnityEngine.Object.Destroy(obj);
}
}
}
poolDict.Clear();
}
}