不管何種語(yǔ)言,對(duì)象的創(chuàng)建與銷毀都需要消耗一定的時(shí)間,Unity3D 也是如此,所以在場(chǎng)景中,如果某些對(duì)象需要頻繁的創(chuàng)建與銷毀,這個(gè)時(shí)候我們經(jīng)常采用對(duì)象池技術(shù),這樣不僅可以降低對(duì)象的創(chuàng)建與銷毀的帶來(lái)的時(shí)間損耗,也是為了降低內(nèi)存的占用。 我們?cè)谧鲰?xiàng)目的時(shí)候,如果同一個(gè)物體要用到好多次,我們就不要再用實(shí)例化了,因?yàn)槊看蝿?chuàng)建一個(gè)新物體是很消耗資源的,引用對(duì)象池技術(shù),顧名思義,把所有要用到的對(duì)象在初始化的時(shí)候都扔到這個(gè)池子里,想用的時(shí)候拿出來(lái)用,不想用的時(shí)候放回去,這樣會(huì)大大節(jié)省資源!
【一共是一個(gè)Demo,兩個(gè)版本,一個(gè)是一個(gè)對(duì)象的儲(chǔ)存與獲取,另一個(gè)版本是多個(gè)游戲?qū)ο蟮膬?chǔ)存與獲取,都寫在一個(gè)類中的,下面就為大家分享一下對(duì)象池的實(shí)現(xiàn)】
DemoName:ObjectPool
Demo下載地址:http://pan.baidu.com/s/1kVdGLHd
using System.Collections;
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 對(duì)象池管理腳本,無(wú)需掛載
/// </summary>
public class ObjectPools
{
#region 對(duì)象池
/// <summary>
/// 對(duì)象池1,創(chuàng)建單個(gè)對(duì)象
/// </summary>
List<GameObject> pools1;
/// <summary>
/// 以字典的方式儲(chǔ)存對(duì)象到池中,int類型key,集合類型的value
/// </summary>
Dictionary<int, List<GameObject>> pools2;
//單例
private static ObjectPools singleton;
/// <summary>
/// 獲取對(duì)象,單例
/// </summary>
/// <returns></returns>
public static ObjectPools GetInstance()
{
if (singleton == null)
{
singleton = new ObjectPools();
}
return singleton;
}
//構(gòu)造函數(shù)初始化對(duì)象池
public ObjectPools()
{
pools1 = new List<GameObject>();
pools2 = new Dictionary<int, List<GameObject>>();
}
#endregion
#region 儲(chǔ)存單個(gè)游戲?qū)ο蟮匠刂?
/// <summary>
/// 儲(chǔ)存單個(gè)游戲?qū)ο蟮匠刂? /// </summary>
/// <param name="gameObject">創(chuàng)建的游戲?qū)ο?lt;/param>
/// <param name="pos">位置</param>
/// <param name="rotation">旋轉(zhuǎn)</param>
/// <returns>返回的對(duì)象</returns>
public GameObject SwpanObject(GameObject gameObject, Vector3 pos, Quaternion rotation)
{
//如果池中的對(duì)象數(shù)量大于0
if (pools1.Count > 0)
{
GameObject result = pools1[0]; //提取第一個(gè)對(duì)象
pools1.Remove(result); //從集合中清除提取的對(duì)象
result.SetActive(true); //設(shè)置當(dāng)前對(duì)象激活
result.transform.position = pos; //設(shè)置對(duì)象的初始位置
result.transform.rotation = rotation; //設(shè)置對(duì)線下的初始旋轉(zhuǎn)
return result; //返回游戲?qū)ο? }
//否則,直接實(shí)例化游戲?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 儲(chǔ)存多個(gè)游戲?qū)ο蟮匠刂?
/// <summary>
/// 實(shí)例化并儲(chǔ)存游戲?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)前對(duì)象的ID(每個(gè)游戲?qū)ο蠖加懈髯缘腎D)
int key = gameObject.GetInstanceID();
//如果池中包含key當(dāng)前游戲?qū)ο蟮膋ey值(游戲?qū)ο蟮腎D)
if (pools2.ContainsKey(key))
{
//如果池中的對(duì)象數(shù)量大于0
if (pools2[key].Count > 0)
{
//提取第一個(gè)對(duì)象(key就是ID(ID就是相對(duì)應(yīng)的游戲?qū)ο螅?代表的是這個(gè)key中第一個(gè)對(duì)象)
GameObject result = pools2[key][0];
result.SetActive(true); //激活顯示當(dāng)前對(duì)象
pools2[key].Remove(result); //從池中清除對(duì)象游戲?qū)ο? result.transform.position = pos; //設(shè)置初始位置
result.transform.rotation = rotation; //設(shè)置初始旋轉(zhuǎn)
return result; //返回提取的游戲?qū)ο? }
}
//否則,實(shí)例化對(duì)象并接收
GameObject res = GameObject.Instantiate(gameObject, pos, rotation) as GameObject;
//儲(chǔ)存游戲?qū)ο蟮腎D,轉(zhuǎn)換成字符串
res.name = gameObject.GetInstanceID().ToString();
//返回場(chǎng)景的游戲?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值對(duì)應(yīng)的游戲?qū)ο? if (!pools2.ContainsKey(key))
{
//添加對(duì)象到池中,并開(kāi)辟value空間
pools2.Add(key, new List<GameObject>());
}
//否則直接添加key對(duì)應(yīng)的游戲?qū)ο蟮匠刂? pools2[key].Add(gameObject);
}
#endregion
#region 協(xié)程,延遲關(guān)閉游戲?qū)ο蟮娘@示
/// <summary>
/// 協(xié)程,延遲隱藏游戲?qū)ο螅瑔蝹€(gè)游戲?qū)ο? /// </summary>
/// <param name="gameObject">隱藏的游戲?qū)ο?lt;/param>
/// <param name="time">隱藏的時(shí)間間隔</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">隱藏的時(shí)間間隔</param>
/// <returns></returns>
public IEnumerator IEDestory2(GameObject gameObject, float time)
{
yield return new WaitForSeconds(time);
GetInstance().DestoryObject2(gameObject);
}
#endregion
}
using UnityEngine;
/// <summary>
/// 對(duì)象池的調(diào)用,掛載到空物體即可
/// </summary>
public class GameManager : MonoBehaviour
{
//儲(chǔ)存單個(gè)游戲?qū)ο蟮綄?duì)象池中
public GameObject player;
//需要利用到對(duì)象池的游戲?qū)ο髷?shù)組(同時(shí)創(chuàng)建多個(gè)游戲?qū)ο螅? public GameObject[] players;
void Update()
{
//單個(gè)游戲?qū)ο蟮牟寮? if (Input.GetMouseButtonDown(2))
{
//按下鼠標(biāo)中鍵的時(shí)候創(chuàng)建一個(gè)游戲?qū)ο? GameObject go =
ObjectPools.GetInstance().SwpanObject(player, Vector3.zero, Quaternion.identity) as GameObject;
//開(kāi)啟協(xié)程,延遲隱藏對(duì)象
StartCoroutine(ObjectPools.GetInstance().IEDestory(go, 2f));
}
//游戲?qū)ο髷?shù)組的創(chuàng)建
if (Input.GetMouseButtonDown(0))
{
//按下左鍵,創(chuàng)建數(shù)組中第1個(gè)游戲?qū)ο? GameObject go = ObjectPools.GetInstance().SwpanObject2(players[0],
Vector3.zero, Quaternion.identity);
//開(kāi)啟協(xié)程,延遲隱藏對(duì)象
StartCoroutine(ObjectPools.GetInstance().IEDestory2(go, 2f));
}
if (Input.GetMouseButtonDown(1))
{
//按下右鍵,創(chuàng)建數(shù)組中第2個(gè)游戲?qū)ο? GameObject go = ObjectPools.GetInstance().SwpanObject2(players[1],
Vector3.zero, Quaternion.identity);
//開(kāi)啟協(xié)程,延遲隱藏對(duì)象
StartCoroutine(ObjectPools.GetInstance().IEDestory2(go, 2f));
}
}
}