13. 对象池

创建对象池

我们后面会创建出很多的卡牌,如果每张卡牌都需要 Instantiate 和 Destroy 的话,就会非常消耗性能。因此我们使用对象池来管理这些对象,使它们的分配和开销减少

具体代码如下

using System.Diagnostics.Tracing;
using UnityEngine;
using UnityEngine.Pool;

public class PoolTool : MonoBehaviour
{
    public GameObject objPrefab;
    private ObjectPool<GameObject> pool;

    private void Start()
    {
        // 初始化对象池
        pool = new ObjectPool<GameObject>(
            createFunc: () => Instantiate(objPrefab, transform),
            actionOnGet: (obj) => obj.SetActive(true),
            actionOnRelease: (obj) => obj.SetActive(false),
            actionOnDestroy: (obj) => Destroy(obj),
            // 是否检查我们的对象
            collectionCheck: false,
            defaultCapacity: 10,
            maxSize: 20
        );

        PreFillPool(7);
    }

    private void PreFillPool(int count) 
    {
        var preFillArray = new GameObject[count];

        for (int i = 0; i < count; i++)
        {
            preFillArray[i] = pool.Get();
        }
        foreach (var item in preFillArray)
        {
            pool.Release(item);
        }
    }

    public GameObject GetObjectFromPool()
    {
        return pool.Get();
    }

    public void ReleaseObjectToPool(GameObject obj)
    {
        pool.Release(obj);
    }
}

在这段代码中,我们使用 new ObjectPool 新建了一个对象池。它创建新对象的时候使用Instantiate,从对象池获取对象的时候使用SetActive(true),将对象释放到对象池的时候使用SetActive(false),销毁对象使用Destroy。同时还指定,不检查对象,默认大小是10,最大大小是20

对象池一开始是不会分配对象的,所以我们需要在 Start 的时候先手动分配一些对象,并把它们返回到对象池中。这就是PreFillPool的实现方式

为了别人可以方便使用 PoolTool,所以我们需要开放两个接口GetObjectFromPoolReleaseObjectToPool,用于从对象池中获取对象,以及将对象返回到对象池中

卡牌管理器

对象池里面现在拥有的对象都是空白的对象,需要给它们进行赋值,这就是 CardManager 的工作了

CardManager 会从 Addressable 中读取所有卡牌类型,然后将它们保存到 cardDataList 中

请注意Addressables.LoadAssetsAsync<CardDataSO>("CardData", null),这句话的意思是读取 Addressable 中 key 为CardData的数据,因此我们需要将之前做的防御牌变成 Addressable

然后把它的标签改成CardData

运行检查结果

对象池成功分配了 7 张卡牌

卡牌管理器成功读到了 CardDataSO

项目相关代码

代码仓库:https://gitee.com/nbda1121440/DreamOfTheKingdom.git

标签:20240304_1428

posted @ 2024-03-04 14:41  hellozjf  阅读(63)  评论(0编辑  收藏  举报