不管何種語言看铆,對象的創(chuàng)建與銷毀都需要消耗一定的時間,Unity3D 也是如此剩彬,所以在場景中酷麦,如果某些對象需要頻繁的創(chuàng)建與銷毀,這個時候我們經(jīng)常采用對象池技術(shù)喉恋,這樣不僅可以降低對象的創(chuàng)建與銷毀的帶來的時間損耗沃饶,也是為了降低內(nèi)存的占用。 我們在做項目的時候轻黑,如果同一個物體要用到好多次糊肤,我們就不要再用實例化了,因為每次創(chuàng)建一個新物體是很消耗資源的氓鄙,引用對象池技術(shù)馆揉,顧名思義,把所有要用到的對象在初始化的時候都扔到這個池子里抖拦,想用的時候拿出來用升酣,不想用的時候放回去,這樣會大大節(jié)省資源!
【一共是一個Demo态罪,兩個版本噩茄,一個是一個對象的儲存與獲取,另一個版本是多個游戲?qū)ο蟮膬Υ媾c獲取复颈,都寫在一個類中的绩聘,下面就為大家分享一下對象池的實現(xiàn)】
DemoName:ObjectPool
Demo下載地址:http://pan.baidu.com/s/1kVdGLHd
using System.Collections;
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 對象池管理腳本,無需掛載
/// </summary>
public class ObjectPools
{
#region 對象池
/// <summary>
/// 對象池1,創(chuàng)建單個對象
/// </summary>
List<GameObject> pools1;
/// <summary>
/// 以字典的方式儲存對象到池中凿菩,int類型key机杜,集合類型的value
/// </summary>
Dictionary<int, List<GameObject>> pools2;
//單例
private static ObjectPools singleton;
/// <summary>
/// 獲取對象,單例
/// </summary>
/// <returns></returns>
public static ObjectPools GetInstance()
{
if (singleton == null)
{
singleton = new ObjectPools();
}
return singleton;
}
//構(gòu)造函數(shù)初始化對象池
public ObjectPools()
{
pools1 = new List<GameObject>();
pools2 = new Dictionary<int, List<GameObject>>();
}
#endregion
#region 儲存單個游戲?qū)ο蟮匠刂?
/// <summary>
/// 儲存單個游戲?qū)ο蟮匠刂? /// </summary>
/// <param name="gameObject">創(chuàng)建的游戲?qū)ο?lt;/param>
/// <param name="pos">位置</param>
/// <param name="rotation">旋轉(zhuǎn)</param>
/// <returns>返回的對象</returns>
public GameObject SwpanObject(GameObject gameObject, Vector3 pos, Quaternion rotation)
{
//如果池中的對象數(shù)量大于0
if (pools1.Count > 0)
{
GameObject result = pools1[0]; //提取第一個對象
pools1.Remove(result); //從集合中清除提取的對象
result.SetActive(true); //設(shè)置當(dāng)前對象激活
result.transform.position = pos; //設(shè)置對象的初始位置
result.transform.rotation = rotation; //設(shè)置對線下的初始旋轉(zhuǎn)
return result; //返回游戲?qū)ο? }
//否則衅谷,直接實例化游戲?qū)ο蟛⒎祷? return GameObject.Instantiate(gameObject, pos, rotation) as GameObject;
}
/// <summary>
/// 隱藏當(dāng)前游戲?qū)ο蟛⑻砑拥匠刂? /// </summary>
/// <param name="gameObejct">游戲?qū)ο?lt;/param>
public void DestoryObject(GameObject gameObejct)
{
//關(guān)閉當(dāng)前游戲?qū)ο箫@示
gameObejct.SetActive(false);
//添加到集合中
pools1.Add(gameObejct);
}
#endregion
#region 儲存多個游戲?qū)ο蟮匠刂?
/// <summary>
/// 實例化并儲存游戲?qū)ο蟮匠刂? /// </summary>
/// <param name="gameObject">被創(chuàng)建的游戲?qū)ο?lt;/param>
/// <param name="pos">位置</param>
/// <param name="rotation">旋轉(zhuǎn)</param>
/// <returns>返回當(dāng)前游戲?qū)ο?lt;/returns>
public GameObject SwpanObject2(GameObject gameObject, Vector3 pos, Quaternion rotation)
{
//獲取到當(dāng)前對象的ID(每個游戲?qū)ο蠖加懈髯缘腎D)
int key = gameObject.GetInstanceID();
//如果池中包含key當(dāng)前游戲?qū)ο蟮膋ey值(游戲?qū)ο蟮腎D)
if (pools2.ContainsKey(key))
{
//如果池中的對象數(shù)量大于0
if (pools2[key].Count > 0)
{
//提取第一個對象(key就是ID(ID就是相對應(yīng)的游戲?qū)ο螅?代表的是這個key中第一個對象)
GameObject result = pools2[key][0];
result.SetActive(true); //激活顯示當(dāng)前對象
pools2[key].Remove(result); //從池中清除對象游戲?qū)ο? result.transform.position = pos; //設(shè)置初始位置
result.transform.rotation = rotation; //設(shè)置初始旋轉(zhuǎn)
return result; //返回提取的游戲?qū)ο? }
}
//否則椒拗,實例化對象并接收
GameObject res = GameObject.Instantiate(gameObject, pos, rotation) as GameObject;
//儲存游戲?qū)ο蟮腎D,轉(zhuǎn)換成字符串
res.name = gameObject.GetInstanceID().ToString();
//返回場景的游戲?qū)ο? return res;
}
/// <summary>
/// 隱藏當(dāng)前游戲?qū)ο蟛⑻砑拥匠刂? /// </summary>
/// <param name="gameObject">游戲?qū)ο?lt;/param>
public void DestoryObject2(GameObject gameObject)
{
//當(dāng)前游戲?qū)ο蟛患せ? gameObject.SetActive(false);
//獲取當(dāng)前游戲?qū)ο蟮膋ey值会喝,轉(zhuǎn)換成int類型
int key = int.Parse(gameObject.name);
//如果池中不包含key值對應(yīng)的游戲?qū)ο? if (!pools2.ContainsKey(key))
{
//添加對象到池中,并開辟value空間
pools2.Add(key, new List<GameObject>());
}
//否則直接添加key對應(yīng)的游戲?qū)ο蟮匠刂? pools2[key].Add(gameObject);
}
#endregion
#region 協(xié)程玩郊,延遲關(guān)閉游戲?qū)ο蟮娘@示
/// <summary>
/// 協(xié)程肢执,延遲隱藏游戲?qū)ο螅瑔蝹€游戲?qū)ο? /// </summary>
/// <param name="gameObject">隱藏的游戲?qū)ο?lt;/param>
/// <param name="time">隱藏的時間間隔</param>
/// <returns></returns>
public IEnumerator IEDestory(GameObject gameObject, float time)
{
yield return new WaitForSeconds(time);
GetInstance().DestoryObject(gameObject);
}
/// <summary>
/// 協(xié)程译红,延遲隱藏游戲?qū)ο笤で眩螒驅(qū)ο髷?shù)組
/// </summary>
/// <param name="gameObject">隱藏的游戲?qū)ο?lt;/param>
/// <param name="time">隱藏的時間間隔</param>
/// <returns></returns>
public IEnumerator IEDestory2(GameObject gameObject, float time)
{
yield return new WaitForSeconds(time);
GetInstance().DestoryObject2(gameObject);
}
#endregion
}
using UnityEngine;
/// <summary>
/// 對象池的調(diào)用,掛載到空物體即可
/// </summary>
public class GameManager : MonoBehaviour
{
//儲存單個游戲?qū)ο蟮綄ο蟪刂? public GameObject player;
//需要利用到對象池的游戲?qū)ο髷?shù)組(同時創(chuàng)建多個游戲?qū)ο螅? public GameObject[] players;
void Update()
{
//單個游戲?qū)ο蟮牟寮? if (Input.GetMouseButtonDown(2))
{
//按下鼠標(biāo)中鍵的時候創(chuàng)建一個游戲?qū)ο? GameObject go =
ObjectPools.GetInstance().SwpanObject(player, Vector3.zero, Quaternion.identity) as GameObject;
//開啟協(xié)程侦厚,延遲隱藏對象
StartCoroutine(ObjectPools.GetInstance().IEDestory(go, 2f));
}
//游戲?qū)ο髷?shù)組的創(chuàng)建
if (Input.GetMouseButtonDown(0))
{
//按下左鍵耻陕,創(chuàng)建數(shù)組中第1個游戲?qū)ο? GameObject go = ObjectPools.GetInstance().SwpanObject2(players[0],
Vector3.zero, Quaternion.identity);
//開啟協(xié)程,延遲隱藏對象
StartCoroutine(ObjectPools.GetInstance().IEDestory2(go, 2f));
}
if (Input.GetMouseButtonDown(1))
{
//按下右鍵刨沦,創(chuàng)建數(shù)組中第2個游戲?qū)ο? GameObject go = ObjectPools.GetInstance().SwpanObject2(players[1],
Vector3.zero, Quaternion.identity);
//開啟協(xié)程诗宣,延遲隱藏對象
StartCoroutine(ObjectPools.GetInstance().IEDestory2(go, 2f));
}
}
}