国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity對(duì)象池和自寫對(duì)象池

這篇具有很好參考價(jià)值的文章主要介紹了Unity對(duì)象池和自寫對(duì)象池。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

一. 什么是對(duì)象池

二、創(chuàng)建對(duì)象池

1、Stack

①Stack類

<1>構(gòu)造函數(shù)

<2>屬性

<3>方法

②Stack對(duì)象池

2、Queue

①Q(mào)ueue類

<1>構(gòu)造函數(shù)

<2>屬性

<3>方法

②Queue對(duì)象池

3.Unity官方對(duì)象池

①Object Pool類

<1>構(gòu)造函數(shù)

<2>屬性

<3>方法

②Object Pool對(duì)象池


一. 什么是對(duì)象池

顧名思義就是一定數(shù)量的已經(jīng)創(chuàng)建好的對(duì)象(Object)的集合。當(dāng)需要?jiǎng)?chuàng)建對(duì)象時(shí),先在池子中獲取,如果池子中沒(méi)有符合條件的對(duì)象,再進(jìn)行創(chuàng)建新對(duì)象,同樣,當(dāng)對(duì)象需要銷毀時(shí),不做真正的銷毀,而是將其setActive(false),并存入池子中,這樣就避免了大量對(duì)象的創(chuàng)建。

好處:降低性能,減少反復(fù)生成和摧毀產(chǎn)生的大量GC。

壞處:

①回收過(guò)程復(fù)雜度增加,在下次使用的同時(shí),需要清空回收前的數(shù)據(jù)。

②生命周期比其他的對(duì)象較長(zhǎng)。

二、創(chuàng)建對(duì)象池

下面提供三種方法,一種是Stack棧,一種是Queue隊(duì)列以及Unity官方封裝的對(duì)象池。

1、Stack

在開始之前我們需要了解Stack是什么,可以將他看成一個(gè)可以什么都裝的容器,特點(diǎn)是后進(jìn)先出,什么意思呢,就像我們上下樓一樣,當(dāng)我們從1樓走上5樓的時(shí)候,我們是從5樓走下來(lái),而不是從1樓走下來(lái)。舉個(gè)“Hello World? ! ”的例子:

進(jìn)棧:

Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ?? ? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎

出棧:

Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎

可以看見是后進(jìn)先出的。

①Stack類

<1>構(gòu)造函數(shù)

Stack():初始化Stack類的新實(shí)例,該實(shí)例為空并且具有默認(rèn)初始容量。

Stack(ICollection):初始化Stack類的新實(shí)例,該實(shí)例包含從指定集合復(fù)制的元素并且具有與所復(fù)制的元素?cái)?shù)相同的初始容量。

Stack(Int32):初始化Stack類的新實(shí)例,該實(shí)例為空并且具有指定的初始容量或默認(rèn)初始容量(這兩個(gè)容量中的較大者)。

<2>屬性

Count:獲取 Stack 中包含的元素?cái)?shù)。

IsSynchronized:獲取一個(gè)值,該值指示是否同步對(duì) Stack 的訪問(wèn)(線程安全)

SyncRoot:獲取可用于同步對(duì) Stack 的訪問(wèn)的對(duì)象。

<3>方法

紅色為常用方法:

Clear():從 Stack 中移除所有對(duì)象。

Clone():創(chuàng)建 Stack 的淺表副本。

Contains(Object):確定某元素是否在 Stack 中。

CopyTo(Array, Int32):從指定的數(shù)組索引處開始,將 Stack 復(fù)制到現(xiàn)有的一維 Array中。

Equals(Object):確定指定對(duì)象是否等于當(dāng)前對(duì)象。(繼承自 Object)

GetEnumerator():返回IEnumerator 的 Stack。

GetHashCode():作為默認(rèn)哈希函數(shù)。(繼承自 Object)

GetType():獲取當(dāng)前實(shí)例的 Type。(繼承自 Object)

MemberwiseClone():創(chuàng)建當(dāng)前 Object 的淺表副本。(繼承自 Object)

Peek():返回位于 Stack 頂部的對(duì)象但不將其移除。

Pop():刪除并返回 Stack 頂部的對(duì)象。

Push(Object):在Stack的頂部插入一個(gè)對(duì)象。

Synchronized(Stack):返回Stack的同步(線程安全)包裝。

ToArray():將 Stack 復(fù)制到新數(shù)組中。

ToString():返回表示當(dāng)前對(duì)象的字符串。(繼承自 Object)

②Stack對(duì)象池

首先寫一個(gè)對(duì)象池接口,畢竟可能我們有著不同的對(duì)象池,直接寫泛型的對(duì)象池,寫個(gè)委托,可以我們?cè)诨厥找约矮@取的時(shí)候,還需要處理其他的邏輯。

public interface IPool<T>
{
    public delegate void CallBack();
    void Get(CallBack callBack = null);
    void Release(T gameobject, CallBack callBack = null);
    void Create();
    void Destroy(T gameobject);
}

然后我們寫一個(gè)BasePool來(lái)實(shí)現(xiàn)IPool接口,其實(shí)看起來(lái)也不是很難,就是對(duì)Stack的進(jìn)棧以及出棧做調(diào)整。

using System.Collections.Generic;
using UnityEngine;

public class BasePool : IPool<GameObject>
{
    protected GameObject insGameObject;
    public Stack<GameObject> pool;
    //創(chuàng)建一個(gè)帶參數(shù)的構(gòu)造函數(shù)是因?yàn)槲业捻?xiàng)目里面有需求,可以根據(jù)直接的需求改或者不要
    public BasePool(GameObject gameObject)
    {
        this.insGameObject = gameObject;
        pool = new Stack<GameObject>();
    }

    public virtual void Create()
    {
        GameObject go = GameObject.Instantiate(insGameObject);
        /*
         * 添加對(duì)應(yīng)的組件....
         */
        pool.Push(go);
        pool.Pop();
    }
    public virtual void Destroy(GameObject gameobject)
    {
    }

    public virtual void Get(IPool<GameObject>.CallBack callBack = null)
    {
        if (pool.Count == 0)
        {
            //當(dāng)pool沒(méi)有東西的時(shí)候就直接創(chuàng)建一個(gè)
            Create();
        }
        else
        {
            //將物體重新拿出來(lái)
            GameObject go = pool.Pop();
          /*
           * 添加對(duì)應(yīng)的組件....
           */
            go.SetActive(true);
        }
        //處理邏輯
        if (callBack != null)
        {
            callBack();
        }
    }
    public virtual void Release(GameObject gameobject, IPool<GameObject>.CallBack callBack = null)
    {
        //回收的時(shí)候需要做什么
        if (callBack != null)
        {
            callBack();
        }
        gameobject.SetActive(false);
        pool.Push(gameobject);
    }
}

?其實(shí)對(duì)于上面來(lái)說(shuō)已經(jīng)是簡(jiǎn)單的弄好了,下面的是怎么使用,創(chuàng)建一個(gè)TestPool繼承BasePool,

using UnityEngine;

public class TestPool : BasePool
{
    public TestPool(GameObject gameObject) : base(gameObject)
    {
        
    }
    public override void Get(IPool<GameObject>.CallBack callBack = null)
    {
        base.Get(callBack);
    }

    public override void Release(GameObject gameobject, IPool<GameObject>.CallBack callBack = null)
    {
        base.Release(gameobject, callBack);
    }

    public override void Destroy(GameObject gameobject)
    {
        base.Destroy(gameobject);
    }
    public override void Create()
    {
        base.Create();
    }
}

?在你需要使用到的地方,按照下方的樣子就可以運(yùn)作起來(lái)了,具體的業(yè)務(wù)要求還是得你自己具體的實(shí)現(xiàn)。

 public void PoolTest()
 {
     //實(shí)例化一個(gè)對(duì)象池
     TestPool testPool = new TestPool(/*傳入需要生成的GameObject*/);
     testPool.Get();
     /*傳入需要生成的GameObject,也可以選著是否重置Game Object上的組件以及重置數(shù)據(jù)*/
     testPool.Release(gameObject,test);
 }
 private void test()
 {
     /*
      處理邏輯
      */
 }

2、Queue

和Stack不同的是,Queue特點(diǎn)是先進(jìn)先出,什么意思呢,我們排隊(duì)買早餐,先排隊(duì)的人可以先買到早餐然后先離開,舉個(gè)“Hello World? ! ”的例子:

進(jìn)列:

?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎? ? ?? ? ? ?Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎

出列:

Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎Unity對(duì)象池和自寫對(duì)象池,Unity,c#,unity,游戲引擎

①Q(mào)ueue類

<1>構(gòu)造函數(shù)

Queue():初始化Queue類的新實(shí)例,該實(shí)例為空,具有默認(rèn)初始容量并使用默認(rèn)增長(zhǎng)因子。

Queue(ICollection):初始化 Queue 類的新實(shí)例,該實(shí)例包含從指定集合復(fù)制的元素,具有與所復(fù)制的元素?cái)?shù)相同的初始容量并使用默認(rèn)增長(zhǎng)因子。

Queue(Int32):初始化 Queue 類的新實(shí)例,該實(shí)例為空,具有指定的初始容量并使用默認(rèn)增長(zhǎng)因子。

Queue(Int32,Single):初始化Queue類的新實(shí)例,該實(shí)例為空,具有指定的初始容量并使用指定的增長(zhǎng)因子。

<2>屬性

Count:獲取Queue中包含的元素?cái)?shù)。

IsSynchronized:獲取一個(gè)值,該值指示是否同步對(duì)Queue的訪問(wèn)(線程安全)

SyncRoot:獲取可用于同步對(duì)Queue的訪問(wèn)的對(duì)象。

<3>方法

紅色為常用方法:

Clear():從Queue中移除所有對(duì)象。

Clone():創(chuàng)建 Queue 的淺表副本。

Contains(Object)確定某元素是否在Queue中。

CopyTo(Array, Int32):從指定數(shù)組索引開始將 Queue 元素復(fù)制到現(xiàn)有一維 Array 中。

Dequeue()移除并返回位于Queue開始處的對(duì)象。

Enqueue(Object)將對(duì)象添加到Queue的結(jié)尾處。

Equals(Object)確定指定對(duì)象是否等于當(dāng)前對(duì)象。(繼承自 Object)

GetEnumerator():返回循環(huán)訪問(wèn) Queue 的枚舉數(shù)。GetHashCode)作為默認(rèn)哈希函數(shù)。(繼承自 Object)

GetType():獲取當(dāng)前實(shí)例的 Type。(繼承自O(shè)bject)

MemberwiseClone():創(chuàng)建當(dāng)前 Object 的淺表副本。(繼承自 Object)

Peek():返回位于 Queue 開始處的對(duì)象但不將其移除。

Synchronized(Queue):返回將包裝原始隊(duì)列并且是線程安全的新的 Queue。

ToArray():將 Queue 元素復(fù)制到新數(shù)組。

ToString():返回表示當(dāng)前對(duì)象的字符串。(繼承自 Object)

TrimToSize():將容量設(shè)置為 Queue 中元素的實(shí)際數(shù)目。

②Queue對(duì)象池

其實(shí)關(guān)于Queue寫的對(duì)象池和Stack寫的對(duì)象池沒(méi)什么區(qū)別只不過(guò)是使用的類不一樣。創(chuàng)建一個(gè)BaseQueuePool的Queue類的對(duì)象池。

using System.Collections.Generic;
using UnityEngine;

public class BaseQueuePool : IPool<GameObject>
{
    protected GameObject insGameObject;

    public Queue<GameObject> pool;
    public void Create()
    {
        GameObject go = GameObject.Instantiate(insGameObject);
        go.SetActive(true);
        pool.Enqueue(go);
        pool.Dequeue();
    }

    public void Destroy(GameObject gameobject)
    {
    }

    public void Get(IPool<GameObject>.CallBack callBack = null)
    {
        if (pool.Count == 0)
        {
            //當(dāng)pool沒(méi)有東西的時(shí)候就直接創(chuàng)建一個(gè)
            Create();
        }
        else
        {
            //將物體重新拿出來(lái)
            GameObject go = pool.Dequeue();
            go.SetActive(true);
        }
        if (callBack != null)
        {
            callBack();
        }
    }

    public void Release(GameObject gameobject, IPool<GameObject>.CallBack callBack = null)
    {
        //回收的時(shí)候需要做什么
        if (callBack != null)
        {
            callBack();
        }
        gameobject.SetActive(false);
        pool.Enqueue(gameobject);
    }
}

然后使用方法是和上面用Stack類寫的用法一樣。

3.Unity官方對(duì)象池

當(dāng)然,不想自己寫對(duì)象池也是可以的,Unity為我們封裝好對(duì)象池。

①Object Pool類

<1>構(gòu)造函數(shù)

public?ObjectPool<T0>(Func<T>?createFunc, Action<T>?actionOnGet, Action<T>?actionOnRelease, Action<T>?actionOnDestroy, bool?collectionCheck, int?defaultCapacity, int?maxSize);

構(gòu)造函數(shù)需要傳入7個(gè)參數(shù),它們按順序分別是:

createFunc:用于在池為空時(shí)創(chuàng)建新實(shí)例。在大多數(shù)情況下,這只是()=> new T()。

actionOnGet:從池中獲取實(shí)例時(shí)調(diào)用。

actionOnRelease:當(dāng)實(shí)例返回到池時(shí)調(diào)用。這可用于清理或禁用實(shí)例。

actionOnDestroy:當(dāng)由于池達(dá)到最大大小而無(wú)法將元素返回到池時(shí)調(diào)用。

collectionCheck:將實(shí)例返回到池時(shí)執(zhí)行集合檢查。如果實(shí)例已經(jīng)在池中,則會(huì)拋出異常。集合檢查只在編輯器。

defaultCapacity:創(chuàng)建堆棧時(shí)使用的默認(rèn)容量。

maxSize:池的最大大小。當(dāng)池達(dá)到最大大小時(shí),返回到池中的任何其他實(shí)例都將被忽略,并可以被垃圾收集。這可以用來(lái)防止池增長(zhǎng)到非常大的規(guī)模

<2>屬性

CountActive:池已創(chuàng)建但當(dāng)前正在使用且尚未返回的對(duì)象數(shù)。

CountAll:活動(dòng)和非活動(dòng)對(duì)象的總數(shù)。

CountInactive:池中當(dāng)前可用的對(duì)象數(shù)。

<3>方法

Clear:刪除所有池項(xiàng)。如果池包含destroy回調(diào)函數(shù),那么它將被池中的每個(gè)項(xiàng)目調(diào)用。

Dispose:刪除所有池項(xiàng)。如果池包含destroy回調(diào)函數(shù),那么它將被池中的每個(gè)項(xiàng)目調(diào)用。

Get:從池中獲取實(shí)例。如果池為空,則將創(chuàng)建一個(gè)新實(shí)例。

Release:將實(shí)例返回到池中。

②Object Pool對(duì)象池

using UnityEngine;
using UnityEngine.Pool;

public class UnityPool : MonoBehaviour
{
    private ObjectPool<GameObject> pool;
    //池子初始化大小
    int poolSize = 20;
    //池子最大數(shù)量
    int poolMaxSize = 100;

    private void Start()
    {
        pool = new ObjectPool<GameObject>(OnCreate, OnGet, OnRelease, OnDestroy, true, poolSize, poolMaxSize);

    }
    /// <summary>
    /// 實(shí)例化對(duì)象
    /// </summary>
    /// <returns></returns>
    private GameObject OnCreate()
    {
        /*實(shí)例化需要使用對(duì)象池的物體*/
        GameObject go = Instantiate();
        /*
         添加需要的組件
        或者其他邏輯
         */
        return go;
    }
    /// <summary>
    /// 獲取對(duì)象池內(nèi)的實(shí)例
    /// </summary>
    /// <param name="object"></param>
    private void OnGet(GameObject obj)
    {
        obj.SetActive(true);
    }
    /// <summary>
    /// 回收實(shí)例到對(duì)象池
    /// </summary>
    /// <param name="obj"></param>
    private void OnRelease(GameObject obj)
    {
        /*
         * 回收前需要的邏輯
         */
        obj.SetActive(false);
    }
    /// <summary>
    /// 銷毀實(shí)例
    /// </summary>
    /// <param name="obj"></param>
    private void OnDestroy(GameObject obj)
    {
        Destroy(obj);
    }
}

?使用方法也是和上方Stack寫的對(duì)象池一樣。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-811200.html

到了這里,關(guān)于Unity對(duì)象池和自寫對(duì)象池的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包