Common(十四)—— ObjectPool对象池

来源:互联网 发布:上班玩游戏 知乎 编辑:程序博客网 时间:2024/06/05 08:04
目录为:Assets/Scripts/Common/文件为ObjectPool.cs这个文件主要定义了一个对象池,可以参考一下.
using UnityEngine;using System;using System.Collections;using System.Collections.Generic;using System.Threading;using System.Linq;//缓存物体类型public enum PoolObjectType{    POT_Effect,     //Effect    POT_MiniMap,    //MiniMap    POT_Entity,     //Entity    POT_UITip,      //UITip    POT_XueTiao,    //血条    //POT_Type2}//缓存池内GameObject的Infopublic class PoolGameObjectInfo{    public string name;    //缓存时间    public float mCacheTime = 0.0f;    //缓存物体类型    public PoolObjectType type;    //如果是特效,特效的显示等级    public EffectLodLevel lodLevel;    #region //拖尾处理    //可以重用    public bool mCanUse = true;    //重置时间    public float mResetTime = .0f;    //拖尾原始时间    public Dictionary<TrailRenderer, float> mTrailTimes = new Dictionary<TrailRenderer, float>();    #endregion}//GameObject缓存池public class PoolInfo{    //缓存队列    public Dictionary<GameObject, PoolGameObjectInfo> mQueue = new Dictionary<GameObject, PoolGameObjectInfo> ();}//总的缓存池单例public class GameObjectPool: Singleton<GameObjectPool>{    //缓存GameObject Map    private Dictionary<String, PoolInfo> mPoolDic = new Dictionary<string, PoolInfo> ();    //缓存GameOb节点    private GameObject objectsPool;    //一般的对象所能在缓存池内待的时间,超过了就销毁    private float mCacheTime = 1800.0f;    //删除队列    private List<GameObject> mDestroyPoolGameObjects = new List<GameObject> ();    //取得可用对象    private bool TryGetObject(PoolInfo poolInfo, out KeyValuePair<GameObject, PoolGameObjectInfo> objPair)    {        //个数大于0        if (poolInfo.mQueue.Count > 0)        {            //遍历poolInfo的mQueue            foreach (KeyValuePair<GameObject, PoolGameObjectInfo> pair in poolInfo.mQueue)            {                GameObject go = pair.Key;                PoolGameObjectInfo info = pair.Value;                //是否可重用                if (info.mCanUse)                {                    objPair = pair;                    //取第一个可用的,然后返回true                    return true;                }            }        }        objPair = new KeyValuePair<GameObject, PoolGameObjectInfo> ();        //没有可用的,返回false    }    //获取缓存物体    public GameObject GetGO(String res)    {        //有效性检查        if (null == res)        {            return null;        }        //查找对应pool,如果没有缓存        KeyValuePair<GameObject, PoolGameObjectInfo> pair;        //res对应的poolInfo不存的 || poolInfo对应的pair不存在,,,就从prefab加载一个再返回        if (!mPoolDic.TryGetValue(res, out PoolInfo) || !TryGetObject(PoolInfo, out pair))        {            //新创建            //Debug.LogError("res = " + res);            //ResourceUnit这边放到后面再看            ResourceUnit unit = ResourcesManager.Instance.loadImmediate (res, ResourceType.PREFAB);            if (unit.Asset == null)            {                Debug.Log ("can not find the resource" + res);            }            return GameObject.Instantiate (unit.Asset) as GameObject;        }        //出队列数据        GameObject go = pair.Key;        PoolGameObjectInfo info = pair.Value;        //从缓存池里删掉        PoolInfo.mQueue.Remove (go);        //使有效        EnablePoolGameObject(go, info);        //返回缓存GameObject        return go;    }    //用完了以后就放回pool里面    //销毁并不在这里进行    //这里还用来在ReadPreLoadConfig那部分把预加载的effect放进pool    public void ReleaseGO(String res, GameObject go, PoolObjectType type)    {        //获取缓存节点,设置为不可见位置        if (objectsPool == null)        {            objectsPool = new GameObject ("ObjectPool");            //UIPanel:NGUI里面的            objectsPool.AddComponent<UIPanel> ();            objectsPool.transform.localPosition = new Vector3 (0, -5000, 0);        }        if (null == res || null == go)        {            //Debug.LogError(res + "Release go error");            return;        }        //拖尾处理        if (go.tag == "nopool")        {            GameObject.Destroy (go);            return;        }        PoolInfo poolInfo = null;        //没有就创建        if (!mPoolDic.TryGetValue(res, out poolInfo))        {            poolInfo = new PoolInfo ();            mPoolDic.Add (res, poolInfo);        }        PoolGameObjectInfo poolGameObjInfo = new PoolGameObjectInfo ();        poolGameObjInfo.type = type;        poolGameObjInfo.name = res;        //无效缓存物体        DisablePoolGameObject (go, poolGameObjInfo);        //保存缓存GameObject,会传入相同的go,有隐患        //poolInfo.mQueue.Add(go, poolGameObjInfo);        poolInfo.mQueue [go] = poolGameObjInfo;    }    //设置缓存物体有效    //总的来说就是把go设置为active    //enable以后就取出去用    public void EnablePoolGameObject(GameObject go, PoolGameObjectInfo info)    {        //特效Enable        if (info.type == PoolObjectType.POT_Effect)        {            go.SetActive (true);            //prewarm的情况需要模拟一个周期运行            if (go.tag == "prewarm")            {                go.transform.localPosition = new Vector3 (0, -5000, 0);                ParticleSystem[] particles = go.GetComponentsInChildren<ParticleSystem> (true);                foreach (ParticleSystem part in particles)                {                    if (part.gameObject.tag == "prewarm" && part.loop)                    {                        part.Simulate (part.duration);                        part.Play ();                    }                }                go.transform.localPosition = new Vector3 (0, 0, 0);            }            //拖尾处理            if (go.tag == "trail")            {                ParticleSystem[] particles = go.GetComponentsInChildren<ParticleSystem> (true);                foreach (ParticleSystem part in particles)                {                    part.gameObject.SetActive (true);                }                XffectComponent[] xffects = go.GetComponentsInChildren<XffectComponent> (true);                foreach(XffectComponent xffect in xffects)                {                    xffect.Active ();                }                TrailRenderer[] trailRenders = go.GetComponentsInChildren<TrailRenderer> (true);                //拖尾时间                foreach(TrailRenderer trail in trailRenders)                {                    if (info.mTrailTimes.ContainsKey(trail))                    {                        trail.time = info.mTrailTimes [trail];                    }                }                MeshRenderer[] renders = go.GetComponentsInChildren<MeshRenderer> (true);                foreach(MeshRenderer render in renders)                {                    render.gameObject.SetActive (true);                }            }            go.transform.parent = null;        }        else if (info.type == PoolObjectType.POT_MiniMap)        {            go.SetActive (true);            go.transform.parent = null;        }        else if (info.type == PoolObjectType.POT_Entity)        {            go.SetActive (true);            go.transform.parent = null;        }        else if (info.type == PoolObjectType.POT_UITip)        {            go.SetActive (true);            go.transform.parent = null;        }        else if (info.type == PoolObjectType.POT_XueTiao)        {            //do nothing        }        info.mCacheTime = 0.0f;    }    //设置缓存物体无效    public void DisablePoolGameObject(GameObject go, PoolGameObjectInfo info)    {        //特效Disable        if (info.type == PoolObjectType.POT_Effect)         {            ParticleSystem[] particles = go.GetComponentsInChildren<ParticleSystem> (true);            foreach (ParticleSystem part in particles)            {                //清除所有粒子                part.Clear ();            }            //解绑到poolGameObject节点            go.transform.parent = objectsPool.transform;            //拖尾处理            if (go.tag == "trail")             {                info.mCanUse = false;                TrailRenderer[] trailRenders = go.GetComponentsInChildren<TrailRenderer> ();                foreach (TrailRenderer trail in trailRenders)                {                    info.mTrailTimes [trail] = trail.time;                    trail.time = -10;                }                XffectComponent[] xffects = go.GetComponentsInChildren<XffectComponent> (true);                foreach (XffectComponent xffect in xffects)                {                    xffect.DoFinish ();                    xffect.gameObject.SetActive (false);                }                MeshRenderer[] renders = go.GetComponentsInChildren<MeshRenderer> (true);                foreach (MeshRenderer render in renders)                 {                    render.gameObject.SetActive (false);                }                foreach (ParticleSystem part in particles)                 {                    part.gameObject.SetActive (false);                }            }             else             {                info.mCanUse = true;                go.SetActive (false);            }        }         else if (info.type == PoolObjectType.POT_MiniMap)         {            //go.transform.parent = objectsPool.transform;            go.SetActive (false);        }         else if (info.type == PoolObjectType.POT_Entity)         {            //解绑到poolGameObject节点            go.transform.parent = objectsPool.transform;            go.SetActive (false);        }         else if (info.type == PoolObjectType.POT_UITip)        {            //解绑到poolGameObject节点            go.transform.parent == objectsPool.transform;            go.SetActive (false);        }        else if (info.type == PoolObjectType.POT_XueTiao)        {            go.transform.parent = objectsPool.transform;            XueTiaoUI xt = go.GetComponent<XueTiaoUI> ();            xt.SetVisible (false);        }    }    //清除    public void Clear()    {        mPoolDic.Clear ();        mDestroyPoolGameObjects.Clear ();        objectsPool = null;    }    float mTotalTime = 0;    public void OnUpdate()    {        //每隔0.1更新一次        mTotalTime += Time.deltaTime;        if (mTotalTime <= 0.1f)        {            return;        }        else        {            mTotalTime = 0;        }        float deltaTime = Time.deltaTime;        //遍历数据        foreach(PoolInfo poolInfo in mPoolDic.Values)        {            //死亡列表            mDestroyPoolGameObjects.Clear ();            foreach (KeyValuePair<GameObject, PoolGameObjectInfo> pair in poolInfo.mQueue)            {                GameObject obj = pair.Key;                PoolGameObjectInfo info = pair.Value;                info.mCacheTime += deltaTime;                //mCacheTime默认1800s                float mAllCacheTime = mCacheTime;                //POT_UITip缓存3600s                if (info.type == PoolObjectType.POT_UITip)                {                    mAllCacheTime = 3600.0f;                }                //缓存时间到                //加入DestroyPool                if (info.mCacheTime >= mAllCacheTime)                {                    mDestroyPoolGameObjects.Add (obj);                }                //拖尾重置计时                //如果mCanUs为false,那就等待1s再设置为true,然后就等待下次再使用或销毁                if (!info.mCanUse)                {                    info.mResetTime += deltaTime;                    if (info.mResetTime > 1.0f)                    {                        info.mResetTime = 0.0f;                        info.mCanUse = true;                        obj.SetActive (false);                    }                }            }            //移除掉            //这里说明:缓存池里的物体并不会一直存在,超过mCacheTime没用过的话就销毁,不再占用资源,要用的时候会再重新创建            for (int k = 0; k < mDestroyPoolGameObjects.Count; k++)            {                GameObject obj = mDestroyPoolGameObjects [k];                //obj.transform.parent = null;                GameObject.DestroyImmediate (obj);                poolInfo.mQueue.Remove (obj);            }        }    }}
原创粉丝点击