Unity-对象池模块

为什么使用对象池

当一个游戏需要频繁的创建和销毁对象时,为了不增加GC的性能消耗,可以考虑使用回收对象来打到复用的目的。(适用于飞机大战类,消除类,射击类,moba类等游戏)

什么是对象池

为了回收和复用对象,我们使用一个集合来存储不使用的对象,当需要使用该对象时,再从集合中取出,这样一个工具类称之为对象池。

对象池的实现

ObjectPool:对存储对象的集合进行了适当的封装,用于单个游戏对象(预制体)的回收和复用。
PoolManager:对ObjectPool单个游戏对象的进一步封装,可以用于创建多个对象(预制体)的回收和复用,可以更方便的使用对象池。(对象池模块化)
IPoolRelease:对象池回收对象时的还原接口,继承后对象自动还原初始值。

代码

using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 对象池
/// </summary>
public class ObjectPool {

    private GameObject prefab;
    private Stack<GameObject> pool = new Stack<GameObject>();

    public ObjectPool(GameObject _prefab)
    {
        prefab = _prefab;
    }

    //取对象
    public GameObject Get()
    {
        if (pool.Count > 0)
        {
            GameObject go = pool.Pop();
            go.SetActive(true);
            return go;
        }
        else
        {
            GameObject go = GameObject.Instantiate(prefab);
            return go;
        }
    }

    //回收,存对象
    public void Save(GameObject go)
    {
        go.transform.SetParent(PoolManager.Instance.transform);
        go.SetActive(false);
        //调用回收对象的重置方法,(接口中定义)
        IPoolRelease ipool = go.GetComponent<IPoolRelease >();
        if(ipool!=null)
        {
            ipool.OnReset();
        }
        pool.Push(go);
    }
}
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 1.有且只有一个唯一的实例
/// 2.只能自己赋值,别人不能修改(私有的构造)
/// </summary>
public class PoolManager : MonoBehaviour {

    //私有的静态实例
    private static PoolManager _instance = null;

    //懒汉式 单例模式
    //共有的唯一的,全局访问点
    public static PoolManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = GameObject.FindObjectOfType<PoolManager>();
                if (_instance == null)
                {
                    GameObject go = new GameObject("PoolManager");
                    _instance = go.AddComponent<PoolManager>();
                }
            }
            return _instance;
        }
    }


    public GameObject[] prePrefabs;

    //饿汉式 单例模式
    private void Awake()
    {
        if (_instance == null)
            _instance = this;
        else
            Destroy(gameObject);


        InitPool();
    }

    private Dictionary<string, ObjectPool> dic = new Dictionary<string, ObjectPool>();


    void InitPool()
    {
        //提前初始化的对象池
        foreach (var prefab in prePrefabs)
        {
            CreatPool(prefab.name, prefab);
        }
    }
    /// <summary>
    /// 创建对象池
    /// </summary>
    /// <param name="poolName">对象池名字</param>
    /// <param name="prefab">对象池对应的预制体</param>
    public void CreatPool(string poolName,GameObject prefab)
    {
        if (!dic.ContainsKey(poolName))
        {
            dic[poolName] = new ObjectPool(prefab);
        }
    }

    /// <summary>
    /// 获取对象池对象
    /// </summary>
    /// <param name="poolName">对象池名字</param>
    /// <returns></returns>
    public GameObject Get(string poolName)
    {
        ObjectPool pool;
        if(dic.TryGetValue(poolName,out pool))
        {
            return pool.Get();
        }
        else
        {
            Debug.LogError("对象池:" + poolName + " 不存在!!!");
            return null;
        }
    }

    /// <summary>
    /// 回收对象
    /// </summary>
    /// <param name="poolName">对象池的名字</param>
    /// <param name="go">对象</param>
    public void Save(string poolName,GameObject go)
    {
        ObjectPool pool;
        if (dic.TryGetValue(poolName, out pool))
        {
            pool.Save(go);
        }
        else
        {
            Debug.LogError("对象池:" + poolName + " 不存在!!!");
        }
    }
}
public interface IPoolRelease {
    void OnReset();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 这部分主要讨论了AssetBundle的如下知识: AssetBundle的基础知识 使用AssetBundle的...
    Wenchao阅读 1,855评论 0 5
  • 翻译:莫铭原文地址:AssetBundle usage patterns 本系列中的上一篇文章覆盖了AssetBu...
    莫铭阅读 5,735评论 1 12
  • 原文地址:http://gad.qq.com/article/detail/7180936作者:Loki+XUni...
    重装机霸阅读 8,592评论 0 41
  • 这一章来说说AssetBundles,介绍下它的基础系统,还有一些和AssetBundles进行交互的核心API。...
    莫铭阅读 3,131评论 6 10
  • 首先附上原文链接:https://unity3d.com/cn/learn/tutorials/topics/be...
    Bonging阅读 983评论 0 0

友情链接更多精彩内容