Unity3d對(duì)象池技術(shù)的實(shí)現(xiàn)Demo

不管何種語(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));
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Java對(duì)象的生命周期分析 Java對(duì)象的生命周期大致包括三個(gè)階段: 對(duì)象的創(chuàng)建 對(duì)象的使用 對(duì)象的清 因此,對(duì)象...
    jiangmo閱讀 3,621評(píng)論 1 3
  • Unity 對(duì)象池技術(shù) 為什么使用對(duì)象池? 在我們開(kāi)發(fā)中,往往會(huì)遇見(jiàn)需要不斷創(chuàng)建和銷毀同一物體的情況。(如飛機(jī)大戰(zhàn)...
    胤醚貔貅閱讀 803評(píng)論 0 0
  • (一) 裝,裝腔作勢(shì)和服裝,有著同樣的“裝”,卻裝的不同。 從出生,我就開(kāi)始了“裝”,裝作聽(tīng)話的小孩,讓父母省心。...
    果慧_631e閱讀 401評(píng)論 4 1
  • 來(lái)英三年,機(jī)緣巧合發(fā)現(xiàn)了一個(gè)古跡版的 Airbnb 機(jī)構(gòu) Landmark Trust,讓我這種有精品酒店情結(jié)、又...
    納谷nakko閱讀 667評(píng)論 2 7
  • 作者:簡(jiǎn)言君趙鵬 人不能無(wú)緣無(wú)故擁有一件好東西。所以,每當(dāng)我看到一個(gè)很喜歡的東西時(shí),便會(huì)問(wèn)自己:你憑什么擁有它? ...
    簡(jiǎn)言君趙鵬閱讀 710評(píng)論 1 14