Unity--林老师写的高级对象池

由于学疏才浅,看不懂其中的奥妙,只会使用,在这里分享给大家,林老师牛逼~

/********************************用法说明************************
 * 
 * ****************************(对象池工具)**********************
 * 
 *  **************************大吉大利,代码无bug ******************
 *          
 *  使用InitResources方法把resources文件夹下所有物体生成对象池
 * 
 *  如果不想生成全部的物体,使用InitResources方法把resources文件夹下T类型物体生成对象池
 * 
 *  如果不想生成Resources文件夹上面的物体 ,使用InitObject方法把一个具体的物体生成对象池
 *      
 *  如果具体的物体很多的化,使用InitObjects方法把一堆具体的物体生成对象池        
 *                  
 *  通过GetObj名字去对象池里面拿物体,默认的物体是不会自动回收的
 *                              
 *  如果要有自动回收功能,那么可以自己实现,也可以让物体挂上继承IRecyclable的脚本,但是代码要换成GetRecycleAbleObj
 *
 *  如果对回收时间不满意,可以自己重写IRecyclable里面的init方法,把时间改长一点 
 *
 *
 *******************************************菜鸟在线    林老师
 *******************************************************2017年10月17日0:58
 ***************************************************************************/

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

namespace UnityEnginePool
{
    public class ObjectPool
    {

        #region 单例模式
        private static ObjectPool _instance;

        public static ObjectPool Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new ObjectPool();
                }
                return _instance;
            }
        }
        #endregion

        #region 成员变量

        private object ct;

        private MethodInfo me;
        //所有生成对象池的库
        public List> mList = new List>();

        //所有生成对象池的物体的字典,用于查询是否生成过,还有查询物体的下标
        public Dictionary mDic = new Dictionary();
        #endregion

        #region 构造函数
        /// 
        /// 构造函数私有化
        /// 
        private ObjectPool()
        {

            //获取这个类
            Type ty = typeof(Creator);
            me = ty.GetMethod("Create");
            ct = Activator.CreateInstance(ty);

        }
        #endregion

        #region 泛型类型初始化到对象池

        /// 
        /// 将Resources文件夹下所有T类型的物体实例化到对象池
        /// 
        /// 要生成的数量.
        /// 写上你要实例化物体的类型.
        public void InitResources(int count) where T : MonoBehaviour
        {
            T[] objs = Resources.LoadAll("");
            for (int i = 0; i < objs.Length; i++)
            {
                InitObject(objs[i], count);
            }
        }

        /// 
        /// 将T类型的单个物体实例化到对象池
        /// 
        /// 要实例化的物体.
        /// 要生成的数量.
        /// 写上你要实例化物体的类型.
        public void InitObject(T obj, int count) where T : MonoBehaviour
        {
            if (mDic.ContainsKey(obj.name))
            {
                return;
            }
            object[] o = new object[2];
            o[0] = obj.gameObject;
            o[1] = count;
            GameObject[] objs = (GameObject[])me.Invoke(ct, o);
            Stack stack = new Stack();
            for (int i = 0; i < objs.Length; i++)
            {
                objs[i].gameObject.SetActive(false);
                stack.Push(objs[i]);
            }
            mList.Add(stack);
            mDic.Add(obj.name, mList.Count - 1);
        }

        /// 
        /// 将T类型的多个物体实例化到对象池
        /// 
        /// 要实例化的物体的数组.
        /// 要生成的数量.
        public void InitObjects(T[] obj, int count) where T : MonoBehaviour
        {
            for (int i = 0; i < obj.Length; i++)
            {
                InitObject(obj[i], count);
            }
        }
        #endregion

        #region 普通类型初始化到对象池

        /// 
        /// 将Resources文件夹下所有GameObject类型的物体实例化到对象池
        /// 
        /// Count.
        public void InitResources(int count)
        {
            GameObject[] objs = Resources.LoadAll("");
            for (int i = 0; i < objs.Length; i++)
            {
                InitObject(objs[i], count);
            }
        }

        /// 
        /// 将GameObject类型的单个物体实例化到对象池
        /// 
        /// 要实例化的物体.
        /// 要生成的数量.
        public void InitObject(GameObject obj, int count)
        {
            if (mDic.ContainsKey(obj.name))
            {
                return;
            }
            object[] o = new object[2];
            o[0] = obj;
            o[1] = count;
            GameObject[] objs = (GameObject[])me.Invoke(ct, o);
            Stack stack = new Stack();
            for (int i = 0; i < objs.Length; i++)
            {
                objs[i].gameObject.SetActive(false);
                stack.Push(objs[i]);
            }
            mList.Add(stack);
            mDic.Add(obj.name, mList.Count - 1);
        }

        /// 
        /// 将GameObject类型的单个物体补充到不够的对象池里
        /// 
        /// 要实例化的物体.
        /// 要生成的数量.
        private void SuppleObject(Stack st, GameObject obj, int count)
        {
            Debug.Log("补充");
            object[] o = new object[2];
            o[0] = obj;
            o[1] = count;
            GameObject[] objs = (GameObject[])me.Invoke(ct, o);
            for (int i = 0; i < objs.Length; i++)
            {
                objs[i].gameObject.SetActive(false);
                st.Push(objs[i]);
            }
        }

        /// 
        /// 将GameObject类型的多个物体实例化到对象池
        /// 
        /// 要实例化的物体的数组.
        /// 要生成的数量.
        public void InitObjects(GameObject[] obj, int count)
        {
            for (int i = 0; i < obj.Length; i++)
            {
                InitObject(obj[i], count);
            }
        }
        #endregion

        /// 
        /// 根据名字拿一个物体
        /// 
        /// 从对象池拿到的物体 .
        /// 物体的名字.
        public GameObject GetObj(string name)
        {
            if (!mDic.ContainsKey(name))
            {
                Debug.LogError("对象池获取失败!!" + "对象池没有你要的这个物体");
                return null;
            }
            GameObject obj = mList[mDic[name]].Pop();
            if (mList[mDic[name]].Count < 2)
            {
                SuppleObject(mList[mDic[name]], obj, 10);
            }
            obj.gameObject.SetActive(true);
            return obj;
        }


        /// 
        /// 根据名字拿一个IRecycleAble的物体
        /// 
        /// 从对象池拿到的物体 .
        /// 物体的名字.
        public GameObject GetRecycleAbleObj(string name)
        {
            if (!mDic.ContainsKey(name))
            {
                Debug.LogError("对象池获取失败!!" + "对象池没有你要的这个物体");
                return null;
            }
            GameObject obj = mList[mDic[name]].Pop();
            if (mList[mDic[name]].Count < 2)
            {
                SuppleObject(mList[mDic[name]], obj, 10);
            }
            obj.gameObject.SetActive(true);
            
            obj.GetComponent().Init(mDic[name]);
            return obj;
        }

        /// 
        /// 回收一个物体
        /// 
        /// 要回收物体的GameObject.
        public void CallBack(GameObject obj)
        {
            if (!mDic.ContainsKey(obj.name))
            {
                Debug.Log("对象池回收失败!!" + obj.name + "不是从对象池出来的");
                return;
            }
            int no = mDic[obj.name];
            mList[no].Push(obj);
            obj.gameObject.SetActive(false);
        }

        /// 
        /// 回收一个IRecycleAble的物体
        /// 
        /// 要回收物体的GameObject.
        public void CallBackIRecycle(IRecyclable obj)
        {
            string name = obj.gameObject.name.Split('(')[0];
            if (!mDic.ContainsKey(name))
            {
                Debug.Log("对象池回收失败!!" + name + "不是从对象池出来的");
                return;
            }
            int no = mDic[name];
            mList[no].Push(obj.gameObject);
            obj.gameObject.SetActive(false);
        }
    }

    public class Creator : MonoBehaviour
    {
        public GameObject[] Create(GameObject obj, int l)
        {
            GameObject[] o = new GameObject[l];
            for (int i = 0; i < l; i++)
            {
                o[i] = Instantiate(obj);
            }
            return o;
        }


    }

    public abstract class IRecyclable : MonoBehaviour
    {

        protected float mTime = 0.0f;

        protected float Duration;

        public float mDuration = 3.0f;


        //初始化函数
        public virtual void Init(int no)
        {
            NO = no;
            mTime = mDuration;
        }



        //被回收的时候调用的函数
        public virtual void OnRecycle()
        {
            ObjectPool.Instance.CallBackIRecycle(this);
        }

        public int NO;

        void Update()
        {
            if (mTime > 0.0f)
            {
                mTime -= Time.deltaTime;
                if (mTime < 0.0f)
                {
                    OnRecycle();
                }
            }
        }
    }

}

你可能感兴趣的:(Unity--林老师写的高级对象池)