Unityオブジェクトプール(マルチプール共存)

7334 ワード

オブジェクトプールを使用するメリットは、毎回オブジェクトを作成して作成する必要がなく、弾丸の発射などの作成に破棄することです.作成した弾丸は、使用後にオブジェクトプールに保存し、使用するときに直接オブジェクトプールから取り出すことができます.
消費電力のパフォーマンスを頻繁に作成および破棄します.
使い方を見て
(ここには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();
        }
    }