using System.Collections.Generic; using UnityEngine; namespace AibisDream.Utility { /// /// 通用对象池管理器 /// public class ObjectPool : MonoBehaviour { [System.Serializable] public class PoolItem { public string tag; public GameObject prefab; public int size; } [Header("对象池配置")] public List poolItems = new List(); private Dictionary> poolDictionary; private Dictionary prefabDictionary; private void Awake() { InitializePools(); } /// /// 初始化所有对象池 /// private void InitializePools() { poolDictionary = new Dictionary>(); prefabDictionary = new Dictionary(); foreach (PoolItem item in poolItems) { Queue objectPool = new Queue(); for (int i = 0; i < item.size; i++) { GameObject obj = CreateNewObject(item.prefab, item.tag); objectPool.Enqueue(obj); } poolDictionary.Add(item.tag, objectPool); prefabDictionary.Add(item.tag, item.prefab); } } /// /// 创建新对象 /// private GameObject CreateNewObject(GameObject prefab, string tag) { GameObject obj = Instantiate(prefab); obj.SetActive(false); // 添加池化组件 PooledObject pooledObj = obj.GetComponent(); if (pooledObj == null) { pooledObj = obj.AddComponent(); } pooledObj.poolTag = tag; return obj; } /// /// 从对象池获取对象 /// public GameObject GetFromPool(string tag, Vector3 position, Quaternion rotation) { if (!poolDictionary.ContainsKey(tag)) { Debug.LogWarning($"对象池中不存在标签: {tag}"); return null; } Queue pool = poolDictionary[tag]; GameObject obj; if (pool.Count > 0) { obj = pool.Dequeue(); } else { // 如果池为空,创建新对象 obj = CreateNewObject(prefabDictionary[tag], tag); } obj.SetActive(true); obj.transform.position = position; obj.transform.rotation = rotation; return obj; } /// /// 从对象池获取对象(使用默认位置和旋转) /// public GameObject GetFromPool(string tag) { return GetFromPool(tag, Vector3.zero, Quaternion.identity); } /// /// 将对象返回池中 /// public void ReturnToPool(GameObject obj) { PooledObject pooledObj = obj.GetComponent(); if (pooledObj == null) { Debug.LogWarning("对象没有PooledObject组件,无法返回池中"); return; } string tag = pooledObj.poolTag; if (!poolDictionary.ContainsKey(tag)) { Debug.LogWarning($"对象池中不存在标签: {tag}"); return; } obj.SetActive(false); poolDictionary[tag].Enqueue(obj); } /// /// 延迟返回对象到池中 /// public void ReturnToPool(GameObject obj, float delay) { StartCoroutine(ReturnToPoolCoroutine(obj, delay)); } private System.Collections.IEnumerator ReturnToPoolCoroutine(GameObject obj, float delay) { yield return new WaitForSeconds(delay); ReturnToPool(obj); } /// /// 清空指定对象池 /// public void ClearPool(string tag) { if (!poolDictionary.ContainsKey(tag)) { Debug.LogWarning($"对象池中不存在标签: {tag}"); return; } Queue pool = poolDictionary[tag]; while (pool.Count > 0) { GameObject obj = pool.Dequeue(); if (obj != null) { Destroy(obj); } } } /// /// 清空所有对象池 /// public void ClearAllPools() { foreach (string tag in poolDictionary.Keys) { ClearPool(tag); } } /// /// 获取池中对象数量 /// public int GetPoolSize(string tag) { if (!poolDictionary.ContainsKey(tag)) { return 0; } return poolDictionary[tag].Count; } /// /// 预加载对象到池中 /// public void PreloadObjects(string tag, int count) { if (!prefabDictionary.ContainsKey(tag)) { Debug.LogWarning($"预制体字典中不存在标签: {tag}"); return; } for (int i = 0; i < count; i++) { GameObject obj = CreateNewObject(prefabDictionary[tag], tag); poolDictionary[tag].Enqueue(obj); } } } /// /// 池化对象组件 /// public class PooledObject : MonoBehaviour { [HideInInspector] public string poolTag; private void OnDisable() { // 当对象被禁用时,自动返回池中 // 注意:这可能会导致问题,如果对象被手动禁用 // 建议在需要时手动调用ReturnToPool } } }