public class ObjectPoolManager : Singleton<ObjectPoolManager>
{
private class InternalPool
{
private Stack<GameObject> m_pool;
private int m_poolDepth;
private GameObject m_poolParent;
public InternalPool(GameObject poolParent, int defPoolDepth)
{
m_pool = new Stack<GameObject>();
m_poolParent = poolParent;
m_poolDepth = defPoolDepth;
}
public void SetPoolDepthAndKeepNum(int poolDepth)
{
if (poolDepth == m_poolDepth)
{
return;
}
m_poolDepth = Mathf.Clamp(poolDepth, 0, 1000);
CleanToDepthNum();
}
public void Release(GameObject go)
{
if (m_pool.Contains(go))
{
go.SetActive(false);
return;
}
if (m_pool.Count >= m_poolDepth)
{
GameObject.Destroy(go);
return;
}
go.SetActive(false);
go.transform.SetParent(m_poolParent.transform);
m_pool.Push(go);
}
public GameObject Get(bool setActive = true)
{
if (m_pool.Count > 0)
{
var go = m_pool.Pop();
if (setActive)
{
go.SetActive(true);
}
go.transform.SetParent(null);
return go;
}
return null;
}
private void CleanToDepthNum()
{
int keepNum = m_poolDepth;
while (m_pool.Count > keepNum)
{
GameObject.Destroy(m_pool.Pop());
}
}
public void Clean()
{
while (m_pool.Count > 0)
{
Object.DestroyImmediate(m_pool.Pop());
}
}
public int GetCount()
{
return m_pool.Count;
}
}
private readonly GameObject m_poolParent;
private readonly Dictionary<string, InternalPool> m_pools;
private readonly Dictionary<string, int> m_poolSeparateDepth;
private int m_defaultPoolDepth;
public int PoolDepth
{
get { return m_defaultPoolDepth; }
set
{
m_defaultPoolDepth = value;
m_defaultPoolDepth = Mathf.Clamp(m_defaultPoolDepth, 0, 1000);
}
}
private ObjectPoolManager()
{
m_defaultPoolDepth = 10;
m_pools = new Dictionary<string, InternalPool>();
m_poolSeparateDepth = new Dictionary<string, int>();
if (m_poolParent == null)
{
m_poolParent = new GameObject("PoolParent");
GameObject.DontDestroyOnLoad(m_poolParent);
}
}
public override void Dispose()
{
GameObject.Destroy(m_poolParent);
m_pools.Clear();
m_poolSeparateDepth.Clear();
base.Dispose();
}
//setactive 专门为了某些需要先前置设置然后才能显示出来的对象
public GameObject Get(string key, bool setActive = true)
{
InternalPool pool = null;
if (m_pools.TryGetValue(key, out pool))
{
return pool.Get();
}
return null;
}
public void Release(string key, GameObject go, bool isIntoPool = true)
{
if (!isIntoPool)
{
GameObject.Destroy(go);
return;
}
if (!m_pools.ContainsKey(key))
{
int depth = 0;
if (!m_poolSeparateDepth.TryGetValue(key, out depth))
{
depth = m_defaultPoolDepth;
}
m_pools.Add(key, new InternalPool(m_poolParent, depth));
}
InternalPool pool = null;
if (m_pools.TryGetValue(key, out pool))
{
pool.Release(go);
}
}
public void Clean()
{
List<string> keys = new List<string>(m_pools.Keys);
for (int i = 0; i != keys.Count; ++i)
{
var pool = m_pools[keys[i]];
pool.Clean();
}
m_poolSeparateDepth.Clear();
}
public int GetGameObjectNum(string key)
{
InternalPool pool = null;
if (m_pools.TryGetValue(key, out pool))
{
return pool.GetCount();
}
return 0;
}
public void SetKeyPoolDepthAndKeepNum(string key, int poolDepth)
{
InternalPool pool = null;
if (m_pools.TryGetValue(key, out pool))
{
pool.SetPoolDepthAndKeepNum(poolDepth);
}
else
{
if (m_poolSeparateDepth.ContainsKey(key))
{
m_poolSeparateDepth[key] = poolDepth;
}
else
{
m_poolSeparateDepth.Add(key, poolDepth);
}
}
}
}
Unity Stack+GameObject.SetActive()实现对象池。
最新推荐文章于 2024-01-28 12:01:57 发布