【Unity】简易对象池

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool<T> where T : new()
{
    /// <summary>
    /// 对象初始化方法
    /// </summary>
    public Func<T> FuncGetNewObject;

    /// <summary>
    /// 对象重用时派发事件
    /// </summary>
    public Action<T> OnEventReuse;

    /// <summary>
    /// 对象回收时派发事件
    /// </summary>
    public Action<T> OnEventRecycle;

    /// <summary>
    /// 对象销毁时派发事件
    /// </summary>
    public Action<T> OnEventDestroy;

    /// <summary>
    /// 对象池
    /// </summary>
    protected Queue<T> pool;

    /// <summary>
    /// 对象池大小
    /// </summary>
    public int PoolCount
    {
        get
        {
            return pool.Count;
        }
    }

    /// <summary>
    /// 对象池构造方法
    /// </summary>
    public ObjectPool()
    {
        pool = new Queue<T>();
    }

    /// <summary>
    /// 获取一个对象,优先从池子里取
    /// </summary>
    /// <returns></returns>
    public T GetOne()
    {
        if (pool.Count > 0)
        {
            T obj = pool.Dequeue();

            OnEventReuse?.Invoke(obj);

            return obj;
        }
        else
        {
            return CreateInstance();
        }
    }

    /// <summary>
    /// 回收一个对象到池子里
    /// </summary>
    /// <param name="obj"></param>
    public void Recycle(T obj)
    {
        if (obj == null) return;

        pool.Enqueue(obj);

        OnEventRecycle?.Invoke(obj);
    }

    /// <summary>
    /// 清理对象池
    /// </summary>
    public void Clear()
    {
        while (PoolCount > 0)
        {
            var obj = pool.Dequeue();

            OnEventDestroy?.Invoke(obj);
        }
    }

    /// <summary>
    /// 创建一个新的对象,如果没有指定创建方法,会默认new一个
    /// </summary>
    /// <returns></returns>
    protected T CreateInstance()
    {
        if (FuncGetNewObject != null)
        {
            return FuncGetNewObject();
        }
        else
        {
            return new T();
        }
    }
}


下面是使用方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class TestData
{
    public int count;
}

public class ObjectPoolTest : MonoBehaviour
{
    ObjectPool<TestData> pool;

    public List<TestData> testDatas = new List<TestData>();

    private void Start()
    {
        int index = 0;

        pool = new ObjectPool<TestData>();
        pool.FuncGetNewObject += () =>
        {
            TestData t = new TestData();
            t.count = index;
            index++;
            return t;
        };
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            for (int i = 0; i < 10; i++)
            {
                var data = pool.GetOne();
                testDatas.Add(data);
            }

            Debug.Log(pool.PoolCount);
        }

        if (Input.GetKeyDown(KeyCode.W))
        {
            var data = pool.GetOne();
            testDatas.Add(data);

            Debug.Log(pool.PoolCount);
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            var data = testDatas[testDatas.Count - 1];
            testDatas.Remove(data);
            pool.Recycle(data);

            Debug.Log(pool.PoolCount);
        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容