U3D框架(三):对象池
程序员文章站
2022-07-08 10:09:43
对象池原理:将子弹之类的物体回收关闭,再次调用的时候打开,这样可以防止数据被频繁的创建和删除。如果只是单个对象池,我们用一个list即可实现。不过为了方便,项目中通常会把这部分单独提炼出来。总游戏池的代码类似如下:using System.Collections;using System.Collections.Generic;using UnityEngine;public class ObjectPool{ public static readonly ObjectP...
对象池原理:将子弹之类的物体回收关闭,再次调用的时候打开,这样可以防止数据被频繁的创建和删除。
如果只是单个对象池,我们用一个list即可实现。
不过为了方便,项目中通常会把这部分单独提炼出来。
总游戏池的代码类似如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
public static readonly ObjectPool Inst = Singleton<ObjectPool>.Inst;
/// <summary>
/// 对象池,字典中与key值对应的是数组(arraylist)(例:key为手枪子弹 对应arraylist[手枪子弹,手枪子弹,手枪子弹。。。。。。 ])。
/// </summary>
private Dictionary<string, List<GameObject>> Pool;
/// <summary>
/// 从对象池中获取对象
/// </summary>
/// <param name="_objName"></param>
/// <returns></returns>
public GameObject GetObj(string _objAffiliation, string _objName)
{
GameObject _result = null;
//判断是否有该名字的对象池 //对象池中有对象
if (Pool.ContainsKey(_objName) && Pool[_objName].Count > 0)
{
//Debug.Log("调用对象池:" + _objName);
//获取这个对象池中的第一个对象
_result = Pool[_objName][0];
if(_result==null) Debug.LogError(Pool[_objName].Count+ _objName);
//激活对象
_result.SetActive(true);
//从对象池中移除对象
Pool[_objName].Remove(_result);
//返回结果
return _result;
}
//如果没有该名字的对象池或者该名字对象池没有对象
//Debug.Log(_objAffiliation + " " + _objName);
GameObject _prefab = /*Main.UploadResource.transform.Find("" + _objAffiliation + "/" + _objName).gameObject;*/
null;
//实例化物体
_result = UnityEngine.Object.Instantiate(_prefab);
//改名 去除Clone
_result.name = _objName;
_result.SetActive(true);
return _result;
}
/// <summary>
/// 回收对象到对象池
/// </summary>
public void RecycleObj(GameObject _obj, bool _isMap = false)
{
if (_obj == null || !_obj.activeInHierarchy) return;
_obj.SetActive(false);
//如果有该对象的对象池,直接放在池子中
if (Pool.ContainsKey(_obj.name))
{
Pool[_obj.name].Add(_obj);
}
else//如果没有该对象的对象池,创建一个该类型的池子,并将对象放入
{
//Debug.Log("新建一个对象池:" + Obj.name);
Pool.Add(_obj.name, new List<GameObject>() { _obj });
}
}
/// <summary>
/// 移除所有的数组
/// </summary>
public void RemoveAll()
{
Pool.Clear();
}
}
单例对象池类似如下:
/// <summary>
/// 简易的池
/// </summary>
public class SimplePool
{
private List<GameObject> objPool;//存储物体的池
private string poolName;
private string path;
//创建池
public void CreatPool(string _name,string _path)
{
objPool = new List<GameObject>();
poolName = _name;
path = _path;
}
//创建物体
public GameObject CreatObj()
{
GameObject obj = null;
if (objPool.Count > 0)
{
obj = objPool[0];
objPool.Remove(obj);
}
else
{
//Debug.Log(path + "/" + poolName);
obj = UnityEngine.Object.Instantiate( Resources.Load(path+ "/" + poolName) as GameObject);
//Debug.Log(obj);
}
obj.name = poolName;
obj.transform.position = -100 * Vector3.one;
obj.SetActive(true);
//Debug.LogError("剩余长度"+objPool.Count);
return obj;
}
//回收物体
public void RecycleObj(GameObject obj)
{
if (obj==null || obj.activeSelf == false) return;
obj.SetActive(false);
objPool.Add(obj);
//Debug.LogError("新增长度" + objPool.Count);
}
//清除池
public void ClearPool()
{
for (var idx = objPool.Count - 1; idx >= 0; idx--)
{
GameObject _obj = objPool[idx];
objPool.Remove(_obj);
GameObject.Destroy(_obj);
}
objPool.Clear();
}
}
需要注意的是,在Resources首次加载物体的时候,会有短暂的卡顿,所以最好对于占用内存比较大的物体,使用异步加载。
本文地址:https://blog.csdn.net/Tel17610887670/article/details/107892624
上一篇: scala的Option类型 scalaOption
下一篇: GPU破解神器Hashcat使用简介