天天看點

Unity架構與資源打包region 單例endregionregion 對象預設體資源管理endregionregion 對象池endregion

對象池

一種通用型的技術,在其他語言中也會用到

  1. 線程池、網絡連接配接池,池是一個思想,将不用的東西暫時用池存起來,等到再次使用的時候再調出來用,節省CPU的排程

  1. 對象

    C#的任何一個類都可以執行個體化一個對象Object

Unity中的遊戲對象GameObject

  1. 思路

    最開始的時候,池中沒有對象,需要生成。用完之後放到池中。再次使用的時候再從池中擷取

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;