简易对象池

只针对资源Obj,不兼容脚本,后面会制作支持全类型的万能对象池

上代码:

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

public class ObjectPool
{
    private GameObject prefab;
    private List<GameObject> poolObjs;
    private string objPath;
    private int totleSize;

    public ObjectPool(string path, int initPoolSize, int totleSize)
    {
        poolObjs = new List<GameObject>();
        objPath = path;
        this.totleSize = totleSize;
        prefab = Resources.Load<GameObject>(path);
        if(prefab == null)
        {
            ProDebug.Logger.LogError("path not res!");
            return;
        }
        
        for (int i = 0; i < initPoolSize; i++)
        {
            GameObject obj = GameObject.Instantiate(prefab);
            Transform tran = obj.transform;
            tran.parent = ObjectPoolManager.Obj.transform;
            tran.localPosition = Vector3.zero;
            tran.localRotation = Quaternion.identity;
            obj.SetActive(false);
            obj.name = prefab.name;
            poolObjs.Add(obj);
        }
    }

    public bool HasObj(GameObject obj)
    {
        return prefab.name == obj.name;
    }

    public GameObject GetObj()
    {
        int objCount = poolObjs.Count;
        if(objCount > 0)
        {
            GameObject target = poolObjs[objCount - 1];
            target.SetActive(true);
            poolObjs.RemoveAt(objCount - 1);
            return target;
        }

        if(prefab == null) prefab = Resources.Load<GameObject>(objPath);
        if (prefab == null)
        {
            ProDebug.Logger.LogError("path not res!");
            return null;
        }
        GameObject obj = GameObject.Instantiate(prefab);
        obj.transform.parent = ObjectPoolManager.Obj.transform;
        obj.name = prefab.name;
        return obj;
    }
        
    public void RecycleObj(GameObject obj)
    {
        obj.SetActive(false);
        if(poolObjs.Count >= totleSize)
        {
            GameObject.Destroy(obj);
            obj = null;
            return;
        }
        Transform tran = obj.transform;
        if(tran.parent != ObjectPoolManager.Obj.transform)
        {
            tran.parent = ObjectPoolManager.Obj.transform;
        }
        tran.localPosition = Vector3.zero;
        tran.localRotation = Quaternion.identity;
        poolObjs.Add(obj);
    }

    public void DoDestroy()
    {
        prefab = null;
        for (int i = 0; i < poolObjs.Count; i++)
        {
            GameObject obj = poolObjs[i];
            GameObject.Destroy(obj);
            obj = null;
        }
        poolObjs.Clear();
        objPath = null;
        totleSize = 0;
    }
}

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

public struct ObjectPoolInfo
{
    public string resPath;
    public int initPoolSize;
    public int totleSize;

    public ObjectPoolInfo(string path, int size, int totleCount = 100)
    {
        resPath = path;
        initPoolSize = size;
        totleSize = totleCount;
    }
}

public class ObjectPoolManager : MonoBehaviour
{
    private static ObjectPoolManager _instance;

    private static object _lock = new object();

    private static GameObject _game;

    public static GameObject Obj
    {
        get
        {
            if (_game == null)
            {
                GameObject go = GameObject.Find("ObjcetPoolManager");
                if (go == null)
                {
                    go = new GameObject();
                    go.name = "ObjcetPoolManager";
                    go.transform.position = Vector3.zero;
                }
                _game = go;
            }
            return _game;
        }
    }

    public static ObjectPoolManager Instance
    {
        get
        {
            if (applicationIsQuitting)
            {
                ProDebug.Logger.LogError("已经销毁了");
                return null;
            }

            lock (_lock)
            {
                if (_instance == null)
                {
                    _instance = Obj.GetComponent<ObjectPoolManager>();

                    if (_instance == null)
                    {
                        _instance = Obj.AddComponent<ObjectPoolManager>();
                    }
                }
                return _instance;
            }
        }
    }

    private static bool applicationIsQuitting = false;

    private Dictionary<string, ObjectPool> objectPools = new Dictionary<string, ObjectPool>();

    private void Awake()
    {
        DontDestroyOnLoad(Obj);
    }

    public void OnDestroy()
    {
        applicationIsQuitting = true;
    }

    /// <summary>
    /// 初始化需要的n个池子
    /// </summary>
    /// <param name="ObjectPoolInfos">池子数据列表</param>
    public void InitPoos(List<ObjectPoolInfo> ObjectPoolInfos)
    {
        for (int i = 0; i < ObjectPoolInfos.Count; i++)
        {
            ObjectPoolInfo info = ObjectPoolInfos[i];
            CreateObjectPool(info.resPath, info.initPoolSize, info.totleSize);
        }
    }

    /// <summary>
    /// 初始化池子
    /// </summary>
    /// <param name="info">池子数据</param>
    public void InitPool(ObjectPoolInfo info)
    {
        CreateObjectPool(info.resPath, info.initPoolSize, info.totleSize);
    }

    /// <summary>
    /// 创建池子
    /// </summary>
    /// <param name="resPath">池子资源路径</param>
    /// <param name="initPoolSize">池子初始大小</param>
    /// <returns></returns>
    ObjectPool CreateObjectPool(string resPath, int initPoolSize, int totleSize)
    {
        if (objectPools.ContainsKey(resPath))
        {
            //ProDebug.Logger.LogError("对象池已经存在");
            return null;
        }

        ObjectPool objectPool = new ObjectPool(resPath, initPoolSize, totleSize);
        objectPools.Add(resPath, objectPool);
        return objectPool;
    }
    
    /// <summary>
    /// 从池子中获得物体
    /// </summary>
    /// <param name="resPath">物体路径</param>
    /// <param name="initPoolSize">如果没初始化过池子,这里面默认创建,参数是池子初始大小</param>
    /// <returns></returns>
    public GameObject GetObj(string resPath, int initPoolSize = 1, int totleSize = 100)
    {
        ObjectPool pool = null;
        if (objectPools.TryGetValue(resPath, out pool))
        {
            return pool.GetObj();
        }
        pool = CreateObjectPool(resPath, initPoolSize, totleSize);
        if(pool == null)
        {
            ProDebug.Logger.LogError("resPath is null");
            return null;
        }
        return pool.GetObj();
    }

    /// <summary>
    /// 回收物体
    /// </summary>
    /// <param name="obj">物体实例</param>
    public void RecycleObj(GameObject obj)
    {
        if (obj == null) return;
        foreach (var item in objectPools)
        {
            ObjectPool pool = item.Value;
            if (pool.HasObj(obj))
            {
                pool.RecycleObj(obj);
                return;
            }
        }
    }

    /// <summary>
    /// 删除制定池子
    /// </summary>
    /// <param name="resPath">池子资源</param>
    public void DestroyPool(string resPath)
    {
        ObjectPool pool = null;
        if(objectPools.TryGetValue(resPath, out pool))
        {
            pool.DoDestroy();
            objectPools.Remove(resPath);
        }
    }

    /// <summary>
    /// 删除所有的池子
    /// </summary>
    public void DestroyAllPool()
    {
        foreach (var item in objectPools)
        {
            item.Value.DoDestroy();
        }
        objectPools.Clear();
    }
}
 

猜你喜欢

转载自blog.csdn.net/aihong_1314/article/details/86490568
今日推荐