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]);
}
}
}
}