简易的对象池单例类

using System.Collections.Generic;
namespace UnityEngine
{
    public class Pool : MonoBehaviour
    {
        static private Pool _this;
        static public Pool instance
        {
            get
            {
                if (_this == null)
                {
                    GameObject pool = new GameObject("Pool");
                    pool.AddComponent<Pool>();
                }
                return _this;
            }
        }
        private Dictionary<string, GameObject> poolPrefab = new Dictionary<string, GameObject>();
        private Dictionary<string, Queue<GameObject>> pools = new Dictionary<string, Queue<GameObject>>();
        private Dictionary<string, int> poolCount = new Dictionary<string, int>();
        public GameObject this[string name]
        {
            get { return GetObj(name); }
            set { RecoverObj(value); }
        }
        private void Awake()
        {
            if (_this == null)
            {
                _this = this;
            }
            else
            {
                Destroy(this.gameObject);
                throw new System.Exception("已经存在有Pool组件的GameOject");
            }
        }
        public void SetDontDestroy()
        {
            DontDestroyOnLoad(this.gameObject);
        }
        //初始化对象池
        //reset:重置transform
        public Pool Init(GameObject prefab, int count = 0, bool reset = false)
        {
            if (prefab == null)
            {
                Debug.LogError("要初始化的对象为空");
            }
            else
            {
                if (poolPrefab.ContainsKey(prefab.name))
                {
                    Debug.LogWarning("已经初始化了:" + prefab.name);
                }
                else
                {
                    poolPrefab.Add(prefab.name, prefab);
                    Queue<GameObject> gos = new Queue<GameObject>();
                    for (int i = 0; i < count; i++)
                    {
                        GameObject go = Instantiate(prefab);
                        if (reset)
                        {
                            go.transform.localPosition = Vector3.zero;
                            go.transform.localRotation = Quaternion.Euler(Vector3.zero);
                            go.transform.localScale = Vector3.one;
                        }
                        go.transform.SetParent(this.transform);
                        go.SetActive(false);
                        gos.Enqueue(go);
                    }
                    pools.Add(prefab.name, gos);
                }
            }
            return instance;
        }
        public bool Has(string name)
        {
            return poolPrefab.ContainsKey(name);
        }
        //设置对象容量
        public void SetResize(string name, int count)
        {
            if (pools.ContainsKey(name))
            {
                if (poolCount.ContainsKey(name))
                {
                    poolCount[name] = Mathf.Max(count, pools[name].Count);
                }
                else
                {
                    poolCount.Add(name, Mathf.Max(count, pools[name].Count));
                }
            }
            else
            {
                Debug.LogErrorFormat("没有{0}这个对象", name);
            }
        }
        private int Stock(string name)
        {
            if (poolCount.ContainsKey(name))
            {
                return poolCount[name];
            }
            return int.MaxValue;
        }
        private void Transfer(string name)
        {
            if (poolCount.ContainsKey(name))
                poolCount[name] = Mathf.Max(--poolCount[name], 0);
        }
        //获取对象
        public GameObject GetObj(string name)
        {
            GameObject temp = null;
            if (poolPrefab.ContainsKey(name))
            {
                if (Stock(name) > 0)
                {
                    if (pools[name].Count > 0)
                    {
                        temp = pools[name].Dequeue();
                        temp.transform.SetParent(null);
                    }
                    else
                    {
                        temp = Instantiate(poolPrefab[name]);
                    }
                    temp.SetActive(true);
                    Transfer(name);
                }
                else
                {
                    Debug.LogWarning(name + "对象数量不足");
                }
            }
            else
            {
                Debug.LogError("没有初始化" + name);
            }
            return temp;
        }
        //回收对象
        //reset:重置transform
        public void RecoverObj(GameObject go, bool reset = false)
        {
            if (go == null) return;
            if (poolPrefab.ContainsKey(go.name))
            {
                go.transform.SetParent(this.transform);
                if (reset)
                {
                    go.transform.localPosition = Vector3.zero;
                    go.transform.localRotation = Quaternion.Euler(Vector3.zero);
                    go.transform.localScale = Vector3.one;
                }
                go.SetActive(false);
                pools[go.name].Enqueue(go);
                return;
            }
            Destroy(go);
        }
        //移除对象
        public void Reomve(string name)
        {
            if (poolPrefab.ContainsKey(name))
            {
                foreach (GameObject go in pools[name])
                {
                    Destroy(go);
                }
                pools[name] = null;
                pools.Remove(name);
                poolPrefab.Remove(name);
            }
        }
        public void Reomve(GameObject go)
        {
            if (go != null)
                Reomve(go.name);
        }
        private void OnDestroy()
        {
            Pool._this = null;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值