using UnityEngine; using System.Collections; using System.Collections.Generic; /// /// 对象池管理类,日常使用一下两个方法即可 /// 取对象Spawn(name/Prefab),回收对象Unspawn(name/Prefab) /// public class PoolManager : MonoBehaviour { private static readonly object lockObj = new object(); private static PoolManager _instance; public static PoolManager Instance { get { if (_instance == null) { lock (lockObj) { PoolManager[] objs = FindObjectsOfType(); if (objs != null) { for (int i = 0; i < objs.Length; i++) { DestroyImmediate(objs[i].gameObject); } } GameObject go = new GameObject("PoolManager"); DontDestroyOnLoad(go); _instance = go.AddComponent(); } } return _instance; } } //预制ID-对象池 集合 private Dictionary poolDic = new Dictionary(); //对象ID-对象池ID 集合 private Dictionary itemDic = new Dictionary(); /// /// 取对象,通过对象实例 /// public GameObject Spawn(GameObject prefab) { if (!poolDic.ContainsKey(prefab.GetInstanceID())) { CreateNewPool(prefab); } GameObject item = poolDic[prefab.GetInstanceID()].Spawn(); if (!itemDic.ContainsKey(item.GetInstanceID())) { itemDic.Add(item.GetInstanceID(), prefab.GetInstanceID()); } else { itemDic[item.GetInstanceID()] = prefab.GetInstanceID(); } return item; } /// /// 回收对象 /// public void Unspawn(GameObject go) { if (itemDic.ContainsKey(go.GetInstanceID())) { int id = itemDic[go.GetInstanceID()]; if (poolDic.ContainsKey(id)) { poolDic[id].Unspawn(go); itemDic.Remove(go.GetInstanceID()); } else { Debug.LogError("回收对象失败 : " + go.name); } } } /// /// 回收某个对象池中所有对象 /// public void ClearPool(GameObject prefab) { int id = prefab.GetInstanceID(); if (poolDic.ContainsKey(id)) { poolDic[id].UnspawnAll(); } else { Debug.LogError("清空对象池失败 : " + prefab.name); } List list = new List(); foreach (int key in itemDic.Keys) { if (itemDic[key] == id) { list.Add(key); } } for (int i = 0; i < list.Count; i++) { itemDic.Remove(list[i]); } } /// /// 回收所有对象池 /// public void ClearAll() { foreach (ObjectPool pool in poolDic.Values) { pool.UnspawnAll(); } itemDic.Clear(); } /// /// 创建一个新的对象池 /// public void CreateNewPool(GameObject prefab) { if (poolDic.ContainsKey(prefab.GetInstanceID())) { Debug.LogError("无法创建新的对象池,当前对象池已存在 : " + prefab.name); return; } ObjectPool pool = new ObjectPool(prefab); poolDic.Add(prefab.GetInstanceID(), pool); } /// /// 创建一个新的对象池,并初始化 /// public void CreateNewPool(GameObject prefab, int initSize) { if (poolDic.ContainsKey(prefab.GetInstanceID())) { Debug.LogError("无法创建新的对象池,当前对象池已存在 : " + prefab.name); return; } ObjectPool pool = new ObjectPool(prefab); pool.InitPool(initSize); poolDic.Add(prefab.GetInstanceID(), pool); } /// /// 创建一个新的对象池,并初始化,同时设定对象池最大容量 /// public void CreateNewPool(GameObject prefab, int initSize, int maxSize) { if (poolDic.ContainsKey(prefab.GetInstanceID())) { Debug.LogError("无法创建新的对象池,当前对象池已存在 : " + prefab.name); return; } ObjectPool pool = new ObjectPool(prefab, maxSize); pool.InitPool(initSize); poolDic.Add(prefab.GetInstanceID(), pool); } } /// /// 对象池-子池 /// public class ObjectPool { //对象池元素 public GameObject prefab; //对象池最大容量,此值小于等于0时,对象池动态增加,不设上限 private int maxSize; //对象池名称 public string Name { get { return prefab.name; } } //对象池当前容量 private int CurrentSize { get { return activeObjectList.Count + inactiveObjectList.Count; } } private List activeObjectList = new List(); //已用对象列表 private List inactiveObjectList = new List(); //待用对象列表 public ObjectPool(GameObject obj) { this.prefab = obj; maxSize = -1; } public ObjectPool(GameObject obj, int maxCount) { this.prefab = obj; maxSize = maxCount; } /// /// 初始化对象池 /// public void InitPool(int initSize) { if (maxSize > 0 && initSize > maxSize) { Debug.LogError("对象池初始容量不能超过其最大容量!!"); for (int i = 0; i < maxSize; i++) { GameObject go = GameObject.Instantiate(prefab); go.name = prefab.name; go.SetActive(false); inactiveObjectList.Add(go); } } else { for (int i = 0; i < initSize; i++) { GameObject go = GameObject.Instantiate(prefab); go.name = prefab.name; go.SetActive(false); inactiveObjectList.Add(go); } } } /// /// 取对象 /// public GameObject Spawn() { if (inactiveObjectList.Count == 0) { if (maxSize > 0 && CurrentSize >= maxSize) { Debug.LogError("警告:对象池 " + Name + " 当前容量已达到最大设定值 : " + maxSize); GameObject go = activeObjectList[0]; return go; } else { GameObject go = GameObject.Instantiate(prefab); go.SetActive(true); activeObjectList.Add(go); return go; } } else { GameObject go = inactiveObjectList[0]; go.SetActive(true); inactiveObjectList.RemoveAt(0); activeObjectList.Add(go); return go; } } /// /// 回收对象 /// public void Unspawn(GameObject go) { if (activeObjectList.Contains(go)) { go.SetActive(false); activeObjectList.Remove(go); inactiveObjectList.Add(go); } else { Debug.LogError("回收对象异常,当前对象不在对象列表中!!"); } } /// /// 回收池中所有对象 /// public void UnspawnAll() { //回收修改 int count = activeObjectList.Count; for (int i = 0; i < count; i++) { if (activeObjectList.Count >= 1) { Unspawn(activeObjectList[0]); } } } }