在开发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();
}
}