ObjectPool

来源:互联网 发布:架子鼓扒谱软件 编辑:程序博客网 时间:2024/06/05 08:21


对象池:


using UnityEngine;

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


//对象池管理器
public class PoolManagerOfGameObject : MonoBehaviour
{
    private static PoolManagerOfGameObject instance;
    public static PoolManagerOfGameObject Instance
    {
        get
        {
            if (instance == null)
                instance = new GameObject("PoolManagerOfGameObject").AddComponent<PoolManagerOfGameObject>();
            return instance;
        }
    }


    void Awake()
    {
        instance = this;
    }




    public List<PoolOfGameObject> poolList = new List<PoolOfGameObject>();//对象池列表




    /// <summary>
    /// 创建对象池
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="Count"></param>
    public void New(GameObject obj, int Count = 2)
    {
        _New(obj, Count);
    }


    /// <summary>
    /// 创建对象池
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="Count"></param>
    /// <returns></returns>
    private int _New(GameObject obj, int Count = 2)
    {
        int ID = GetPoolID(obj);
        if (ID != -1)
        {
            poolList[ID].MatchObjectCount(Count);
        }
        else
        {
            PoolOfGameObject pool = new PoolOfGameObject();
            pool.prefab = obj;
            pool.MatchObjectCount(Count);
            poolList.Add(pool);
            ID = poolList.Count - 1;
        }
        return ID;
    }




    /// <summary>
    /// 生成方法
    /// </summary>
    public GameObject Spawn(GameObject obj)
    {
        return _Spawn(obj, Vector3.zero, Quaternion.identity);
    }


    private  GameObject _Spawn(GameObject obj, Vector3 pos, Quaternion rot)
    {
        if (obj == null)
        {
            Debug.LogError("想要产生的东西为空!");
            return null;
        }


        int ID = GetPoolID(obj);
        if (ID == -1) ID = _New(obj);
        return poolList[ID].Spawn(pos, rot);
    }




    /// <summary>
    /// 回收方法
    /// </summary>
    public void Unspawn(GameObject obj)
    {
        _Unspawn(obj);
    }


    private void _Unspawn(GameObject obj)
    {
        if (obj == null)
        {
            Debug.LogError("回收的物体为空");
        }


        for (int i = 0; i < poolList.Count; i++)
        {
            if (poolList[i].UnSpawn(obj)) return;
        }
        Destroy(obj);
    }




    /// <summary>
    /// 在对象池List中获取目标对象池索引
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public int GetPoolID(GameObject obj)
    {
        for (int i = 0; i < poolList.Count; i++)
        {
            if (poolList[i].prefab == obj)
                return i;
        }
        return -1;
    }


    /// <summary>
    /// 内存释放
    /// </summary>
    void OnDestroy()
    {
        for (int i = 0; i < poolList.Count; i++)
        {
            poolList[i].Clear();
        }
    }


    /// <summary>
    /// 多个对象池中每个对象的父物体
    /// </summary>
    /// <returns></returns>
    public Transform GetParent()
    {
        return this.transform;
    }


    /// <summary>
    /// 设置父物体
    /// </summary>
    /// <param name="parent"></param>
    /// <returns></returns>
    public Transform GetParent(Transform parent)
    {
        return parent;
    }
}




//对象池 每个对象都有一个对象池
[SerializeField]
public class PoolOfGameObject
{
    public GameObject prefab;//预制体


    public List<GameObject> inactiveList = new List<GameObject>();//隐藏列表
    public List<GameObject> activeList = new List<GameObject>();//显示列表


    public int capCount = 1000;




    /// <summary>
    /// 创建
    /// </summary>
    public GameObject Spawn(Vector3 pos, Quaternion rot)
    {
        GameObject obj = null;
        if (inactiveList.Count <= 0)
        {
            obj = GameObject.Instantiate(prefab, pos, rot) as GameObject;
            if (!obj.activeSelf)
                obj.SetActive(true);
        }
        else
        {
            obj = inactiveList[0];
            if (inactiveList == null)
            {
                Debug.LogError("对象池中的物体为空");
                inactiveList.RemoveAt(0);
            }
            obj.transform.parent = null;
            obj.transform.position = pos;
            obj.transform.rotation = rot;
            obj.SetActive(true);
            inactiveList.RemoveAt(0);
        }


        activeList.Add(obj);
        return obj;
    }




    /// <summary>
    /// 回收 能回收就回收, 不能回收就删除掉 给Manager提供方法
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public bool UnSpawn(GameObject obj)
    {
        if (activeList.Contains(obj))
        {
            if (obj == null)
                Debug.LogError("回收物体为空");
            obj.SetActive(false);
            obj.transform.parent = PoolManagerOfGameObject.Instance.GetParent();
            activeList.Remove(obj);
            inactiveList.Add(obj);
            return true;
        }


        if (inactiveList.Contains(obj))
        {
            return true;
        }


        return false;
    }


    /// <summary>
    /// 创建一定数量的物体
    /// </summary>
    /// <param name="Count"></param>
    public void MatchObjectCount(int Count)
    {
        if (Count > capCount) return;
        int currentCount = GetTotalObjectCount();
        for (int i = currentCount; i < Count; i++)
        {
            GameObject obj = (GameObject)MonoBehaviour.Instantiate(prefab);
            obj.SetActive(false);
            obj.transform.parent = PoolManagerOfGameObject.Instance.GetParent();
            inactiveList.Add(obj);
        }
    }


    /// <summary>
    /// 创建一定数量的物体并且返回一个实例化后的物体
    /// </summary>
    /// <param name="Count"></param>
    /// <param name="gameObject"></param>
    public void MatchObjectCount(int Count, ref GameObject gameObject)
    {
        if (Count > capCount) return;
        int currentCount = GetTotalObjectCount();
        GameObject obj = null;
        for (int i = currentCount; i < Count; i++)
        {
            obj = (GameObject)MonoBehaviour.Instantiate(prefab);
            obj.SetActive(false);
            obj.transform.parent = PoolManagerOfGameObject.Instance.GetParent();
            inactiveList.Add(obj);
        }
        gameObject = obj;
    }


    /// <summary>
    /// 获取对象池中的数量
    /// </summary>
    /// <returns></returns>
    public int GetTotalObjectCount()
    {
        return inactiveList.Count + activeList.Count;
    }


    /// <summary>
    /// 清空
    /// </summary>
    public void Clear()
    {
        for (int i = 0; i < inactiveList.Count; i++)
        {
            if (inactiveList[i] != null) MonoBehaviour.Destroy(inactiveList[i]);
        }
        for (int i = 0; i < activeList.Count; i++)
        {
            if (activeList[i] != null) MonoBehaviour.Destroy(inactiveList[i]);
        }
    }


}
0 0
原创粉丝点击