Unity 对象池 (多池共存)

       使用对象池的好处就是:不用每次都创建对象然后销毁在创建,比如子弹的发射,当创建好的子弹,可以在使用后保存到对象池里面,当用的时候直接从对象池中取即可。

频繁的创建和销毁耗性能。

先看使用方法

(这里有一个TimerEvnt脚本和一个单例脚本是我之前写的自定义定时器)   

连接: 点我跳转 TimerEvent.cs 

连接: 点我跳转单例博文

也可以自己把这个脚本写成单例 , 计时器那个只是我方便测试功能用的你也可以不用看

private void Awake()
    {

        //初始化两个池子 PoolType.TEST1和PoolType.TEST2
        MgrPool.Instance.InitPool(PoolType.TEST1, new GameObject("TEST1"), 5);
        MgrPool.Instance.InitPool(PoolType.TEST2, new GameObject("TEST2"), 5);

        //这个定时器是我测试功能用的 你们可以不用看
        TimerEvent timerEvent = new TimerEvent(10f, () =>
        {
            MgrPool.Instance.ClaerAll();
            Debug.Log(" 10秒后清理所有池子 ");
        });
        timerEvent.Start();
    }

    //点击事件 
    public void OnClickBtn() 
    {
        //点击后从PoolType.NULL池子取出一个
        GameObject go = MgrPool.Instance.Get(PoolType.TEST1);
        go.transform.SetParent(this.transform);
        go.transform.position = Vector3.zero;
       
        //1秒后回收
        TimerEvent timerEvent = new TimerEvent(1f, () =>
        {
            MgrPool.Instance.Put(PoolType.TEST1, go);
        });
        timerEvent.Start();
       
    }
using System;
using System.Collections.Generic;
using UnityEngine;


    //*****************************自定义对象池类型 可单独创建一个脚本**************************************************************//
    public enum PoolType
    {
        DEFAULT,
        TEST1,
        TEST2,
    }
    public class MgrPool : SingletonBase
    {
        //所有池子的字典
        private Dictionary> _poolDic = new Dictionary>();
        //所有池子类型节点
        private Dictionary _pathDic = new Dictionary();
        //池子容量不够用时候默认扩充数量
        private int _expansion = 5;
        //把所有池子归到统一节点下
        private Transform _poolTotal;
        //是否统一管理池子节点
        private bool _unifiedMgr = true;



        /// 
        /// 初始化
        /// 
        /// 对象池类型
        /// Obj
        /// 初始化大小
        public void InitPool(PoolType poolType, GameObject prefab, int count = 20)
        {
            //创建个MgrPool节点 把所有池子都归到这个节点下 方便管理
            if (_poolTotal == null) _poolTotal = new GameObject("MgrPool").transform;

            if (!_poolDic.ContainsKey(poolType))
            {
                if (_unifiedMgr)
                {
                    //如果是新池子 创建一个节点
                    Transform parent = new GameObject("Pool_" + poolType.ToString()).transform;
                    parent.SetParent(_poolTotal);
                    _pathDic.Add(poolType, parent);
                }
                _poolDic.Add(poolType, new Queue());
                CreatorItem(poolType, prefab, count);
            }
            else
            {
                throw new Exception(string.Format("该池子:'{0}'已存在,请勿重复初始化!", poolType));
            }
        }

        /// 
        /// 从池子里取出
        /// 
        /// 池子类型
        /// 
        public GameObject Get(PoolType poolType)
        {
            if (_poolDic.ContainsKey(poolType) && _poolDic[poolType].Count > 0)
            {
                Queue goQueue = _poolDic[poolType];
                GameObject prefab = null;
                //这里留一个扩充池子用
                if (goQueue.Count > 1)
                {
                    prefab = goQueue.Dequeue();
                    prefab.SetActive(true);
                }
                //这里如果池子空间只剩下一个 就扩容池子
                if (prefab == null && goQueue.Count <= 1)
                {
                    CreatorItem(poolType, goQueue.Peek(), _expansion);
                    return Get(poolType);
                }
                return prefab;
            }
            else
            {
                throw new Exception(string.Format("该池子:'{0}'不存在或已被清理,请先初始化!", poolType));
            }
        }

        public void Put(PoolType poolType, GameObject prefab)
        {
            if (!_poolDic.ContainsKey(poolType))
            {
                if (prefab != null) Destroy(prefab);
                //throw new Exception(string.Format("该池子:'{0}'不存在或已被清理,请先初始化!", poolType));
                Debug.LogWarning("该池子:'" + poolType + "'不存在或已被清理,请先初始化!");
            }
            else
            {
                if (_unifiedMgr)
                {
                    prefab.transform.SetParent(_pathDic[poolType]);
                }
                prefab.SetActive(false);
                _poolDic[poolType].Enqueue(prefab);
            }
        }

        /// 
        /// 创建池子预制
        /// 
        /// 池子类型
        /// 预制
        /// 多少个
        private void CreatorItem(PoolType poolType, GameObject go, int count)
        {
            if (!_poolDic.ContainsKey(poolType))
            {
                throw new Exception(string.Format("该池子:'{0}'不存在或已被清理,请先初始化!", poolType));
            }
            for (int i = 0; i < count; i++)
            {
                GameObject goItem = Instantiate(go, Vector3.zero, Quaternion.identity);
                goItem.transform.SetParent(_unifiedMgr ? _pathDic[poolType] : _poolTotal);
                goItem.name = go.name;
                goItem.SetActive(false);
                _poolDic[poolType].Enqueue(goItem);
            }
        }

        /// 
        /// 清理池子
        /// 
        /// 池子类型
        public void Clear(PoolType poolType)
        {
            if (!_poolDic.ContainsKey(poolType))
            {
                throw new Exception(string.Format("该池子:'{0}'不存在或已被清理,请先初始化!", poolType));
            }
            else
            {
                if (_unifiedMgr)
                {
                    Destroy(_pathDic[poolType].gameObject);
                    _pathDic.Remove(poolType);
                }
                else
                {
                    foreach (GameObject poolItem in _poolDic[poolType])
                    {
                        Destroy(poolItem);
                    }
                }
                _poolDic[poolType].Clear();
                _poolDic.Remove(poolType);

            }

        }
        /// 
        /// 清理所有池子
        /// 
        public void ClaerAll()
        {
            if (_unifiedMgr)
            {
                if (_poolTotal != null) Destroy(_poolTotal.gameObject);
                _pathDic.Clear();
            }
            else
            {
                foreach (Queue queue in _poolDic.Values)
                {
                    foreach (GameObject go in queue)
                    {
                        Destroy(go);
                    }
                }
            }
            _poolDic.Clear();
        }
    }


 

你可能感兴趣的:(Unity)