Unity——对象池

在开发Unity游戏时常常需要使用同一个Prefab来创建多个的对象,如果创建的数量少时还好,不会影响效果,如果需要大量生成时,反复实例化和销毁,不停的消耗内存,出现卡顿甚至卡死现象。为了解决大量创建重复对象造成的内存损耗,采用对象池的方式来解决。在需要创建的时候拿出来,不用的时候放回去,避免反复申请和销毁,损耗内存。

代码如下:

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

public struct _pool
{
    public GameObject _prefab;//预制体
    public bool bActive;//活性
    public int _index;//编号
}
public class ObjectPool : MonoBehaviour
{
    private Dictionary<string, List<_pool>> _prefab = new Dictionary<string, List<_pool>>();//string——预制体名字

    public GameObject CheckActive(GameObject go, int _id)//go需要生成的对象,_id该对象的编号
    {
        GameObject _result = null;
        bool _have = false;//是否存在失活的鱼
        if (_prefab.ContainsKey(go.name))//存在相同的对象名
        {
            List<_pool> _templist = _prefab[go.name];//获取相同对象名的预制体,并查找
            int _count = _templist.Count;
            for (int i = 0; i < _count; i++)
            {
                if (!_templist[i].bActive)//存在多余失活的对象
                {
                    _have = true;
                    _pool po = _templist[i];
                    po.bActive = true;
                    po._prefab.SetActive(true);
                    po._index = _id;//赋值ID
                    _templist[i] = po;
                    _result = po._prefab;
                    break;
                }
            }
            if (!_have)//没有多余的失活对象,则创建
            {
                GameObject GO = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/" + go.name)) as GameObject;
                GO.name = go.name;
                _pool po = new _pool();
                po._prefab = GO;
                po.bActive = true;
                po._prefab.SetActive(true);
                po._index = _id;
                _templist.Add(po);//添加_prefab对象池下go.name的对象
                _prefab[go.name] = _templist;
                _result = po._prefab;

            }
        }
        else
        {
            Dictionary<string, List<_pool>> _temppool = _prefab;
            GameObject GO = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/" + go.name)) as GameObject;//获取该对象
            GO.name = go.name;
            _pool po = new _pool();
            po._prefab = GO;
            po.bActive = true;
            po._prefab.SetActive(true);
            po._index = _id;
            List<_pool> _templist = new List<_pool>();
            _templist.Add(po);
            _temppool.Add(go.name, _templist);//在_prefab对象池中添加该对象
            _prefab = _temppool;
            _result = po._prefab;
        }
        return _result;//返回待生成的对象
    }

    /// <summary>
    /// 回收对象
    /// </summary>
    /// <param name="_id"></param>对象ID
    public void RecyclePrefab(GameObject go, int _id)//go:待回收的对象,_id:编号,查找到,使该对象失活
    {
        if (_prefab.ContainsKey(go.name))
        {
            List<_pool> _templist = _prefab[go.name];//获取相同对象名的预制体,并查找
            int _count = _templist.Count;
            for (int i = 0; i < _count; i++)
            {
                if (_templist[i]._index == _id)
                {
                    _pool po = _templist[i];
                    go.transform.position = new Vector3(3000, 0, 0);
                    go.SetActive(false);//隐藏
                    po._prefab = go;
                    po.bActive = false;//失活
                    po._index = 0;
                    _templist[i] = po;
                    _prefab[go.name] = _templist;
                    break;
                }
            }
        }
    }

    /// <summary>
    /// 清除对象池
    /// </summary>
    public void DestroyPool()
    {
        _prefab.Clear();
    }
}

猜你喜欢

转载自blog.csdn.net/Ro969668074/article/details/81457213
今日推荐