Unity框架與資源打包

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


  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)
{
prefabs = new Dictionary();
pools = new Dictionary>();
resourcePath = resPath;
}

endregion

region 對象預設體資源管理

// 資源加載路徑
private string resourcePath;
// 用字典存儲所有的預設體
private Dictionary prefabs;
// 更新預設體加載路徑
private void UpdateResourcePath(string resPath)
{
resourcePath = 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;
}

endregion

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);
}
// 如果沒有池,或者池中沒有對象,需要生成
else
{
// 拿到預設體
GameObject prefab = GetPrefab(objName);
if (prefab != null)
result = GameObject.Instantiate(prefab);
}
// 激活
result.SetActive(true);

// 執行事件
if (result && poolEvent != null)
poolEvent(result);

// 返回結果
return result;
}

endregion

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章