對象池
一種通用型的技術,在其他語言中也會用到
-
池
線程池、網絡連接配接池,池是一個思想,将不用的東西暫時用池存起來,等到再次使用的時候再調出來用,節省CPU的排程
-
對象
C#的任何一個類都可以執行個體化一個對象Object
Unity中的遊戲對象GameObject
-
思路
最開始的時候,池中沒有對象,需要生成。用完之後放到池中。再次使用的時候再從池中擷取
3.1 回收對象
把對象放到池中
3.2 擷取對象
從池中擷取對象
3.3 代碼實作
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
region 單例
// 聲明單例
private static ObjectPool Instance;
///
/// 擷取單例
/// The instance.
/// Res path.
public static ObjectPool GetInstance(string resPath = "")
if (Instance == null)
if (resPath != "")
Instance = new ObjectPool(resPath);
else
Instance = new ObjectPool();
}
Instance.UpdateResourcePath(resPath);
return Instance;
// 構造函數
private ObjectPool()
prefabs = new Dictionary();
pools = new Dictionary>();
private ObjectPool(string resPath)
resourcePath = resPath;
endregion
region 對象預設體資源管理
// 資源加載路徑
private string resourcePath;
// 用字典存儲所有的預設體
private Dictionary prefabs;
// 更新預設體加載路徑
private void UpdateResourcePath(string resPath)
// 擷取預設體
private GameObject GetPrefab(string prefabName)
// 如果包含預設體,直接傳回
if (prefabs.ContainsKey(prefabName))
return prefabs[prefabName];
// 如果不包含預設體,添加新的預設體,并傳回
return LoadPrefab(prefabName);
// 加載預設體
private GameObject LoadPrefab(string prefabName)
// 拼接路徑
string path = "";
if (resourcePath != "")
path += resourcePath;
GameObject obj = Resources.Load(path + prefabName);
// 存入字典
if (obj != null)
prefabs.Add(prefabName, obj);
// 傳回
return obj;
region 對象池
// 對象池
private Dictionary> pools;
/// 回收對象
/// Object.
public void RecycleObject(GameObject obj)
// 非激活
obj.SetActive(false);
// 擷取對象名稱
string objName = obj.name.Replace("(Clone)", "");
// 判斷有無該類對象池
// 如果沒有,執行個體化一個子池
if (!pools.ContainsKey(objName))
pools.Add(objName, new List());
// 存入
pools[objName].Add(obj);
/// 擷取對象
/// The object.
/// Object name.
/// Pool event.
public GameObject SpawnObject(string objName, System.Action poolEvent = null)
// 聲明一個輸出結果
GameObject result = null;
// 如果有池,并且池中有對象
if (pools.ContainsKey(objName) && pools[objName].Count > 0)
result = poolsobjName;
pools[objName].Remove(result);
// 如果沒有池,或者池中沒有對象,需要生成
// 拿到預設體
GameObject prefab = GetPrefab(objName);
if (prefab != null)
result = GameObject.Instantiate(prefab);
// 激活
result.SetActive(true);
// 執行事件
if (result && poolEvent != null)
poolEvent(result);
// 傳回結果
return result;