当前位置:网站首页>D41_缓冲池
D41_缓冲池
2022-08-05 05:18:00 【没那么简单GG】
为什么要用到缓冲池呢,怎么使用缓冲池呢?在以往的学习中,对于特效,子弹等总是频繁的创建与销毁,这无疑是增加了CPU的负担,为了节省计算量,我们就可以使用缓冲池。
缓冲池,可以想象为储物盒,而游戏物体可以想象为一次性筷子,当我们吃饭的时候,需要用到一次性筷子,吃完了以后随手便扔掉了,这无疑是消耗了资源的,于是我们使用家用的筷子,用过以后洗一洗,放在储物盒里面等着下次吃饭的时候再次用,而当这次买的筷子不够的时候我们才会重新买一批筷子,这无疑是节省了部分资源,却也浪费了一点储存空间,因为筷子不用的时候总是要放在储物盒里,故,缓冲池是用空间换取了时间。
代码原理便是创建一个集合(储物盒),需要实例化游戏物体之前先在集合中看一下有没有这个游戏物体(筷子),如果没有,便实例化(买)一个,如果有的话,便把这个游戏物体拿出来用——将它激活;需要删除一个游戏物体(筷子)的时候,直接使其失活即可。
下面来展示代码:
public class ObjectPool : MonoBehaviour
{
public static ObjectPool Instance;//先来一个单例
private void Awake()
{
Instance = this;
}
List<GameObject> pool = new List<GameObject>();
public GameObject InstantiatePool(string gameObjectName)
{
GameObject go = null;
if (pool.Count <= 0)//如果集合里没有这个游戏物体便创建一个
{
go = GameObject.Instantiate(Resources.Load("Prefabs/" + gameObjectName) as GameObject);
go.name = gameObjectName;//因为克隆出来的物体都带有(clone),所以需要统一一下名字
}
else
{
go = pool[0];//如果集合里有这个游戏物体,那么就不用再次创建,用这个就行
pool.RemoveAt(0);//把这个游戏物体重集合中删除
}
go.SetActive(true);
go.transform.SetParent(null);
return go;
}
public GameObject InstantiatePool(string gameObjectName,Vector3 position,Quaternion quaternion)
{//重载一下,方便其他类的调用
GameObject go = InstantiatePool(gameObjectName);
go.transform.position = position;
go.transform.rotation = quaternion;
return go;
}
public void RemovePool(GameObject gameObject)
{
pool.Add(gameObject);//把该游戏物体加进集合里
gameObject.SetActive(false);
gameObject.transform.SetParent(transform);
}
}
上面代码中需要用到资源的动态加载,即Resources.Load("Perfabs/"+gameObjectName),需要这个游戏物体的时候再从Resource文件夹中寻找。
那么问题来了,我们的游戏中可不止这一种物体需要频繁的创建销毁,那么每一种我都要写一个吗,故,进阶版缓冲池他来了,类似于储物盒,我们给他细化一下,一片区域放筷子,一片区域放碟子,一片区域放叉子......这样的话,一个盒子便可以解决所有的问题,那么问题来了,这个大盒子该用什么数据类呢,既要能保存集合,又要方便查找。于是于是,我们自然而然就想到了字典。
下面继续展示代码:
(大致相同,只是多加了一层字典,所以就不详细注释了)
public class GameObjectPool : MonoBehaviour
{
public static GameObjectPool Instance;
private void Awake()
{
Instance = this;
}
Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>();
public GameObject InstantiatePool(string gameObjectName)
{
GameObject go = null;
if (pool.ContainsKey(gameObjectName))
{
if (pool[gameObjectName].Count > 0)
{
go = pool[gameObjectName][0];
pool[gameObjectName].RemoveAt(0);
}
}
if (go == null)
{
go = GameObject.Instantiate(Resources.Load("Pool/" + gameObjectName) as GameObject);
go.name = gameObjectName;
}
go.SetActive(true);
go.transform.SetParent(null);
return go;
}
public GameObject InstantiatePool(string gameObjectName, Vector3 position, Quaternion quaternion)
{
GameObject go = InstantiatePool(gameObjectName);
go.transform.position = position;
go.transform.rotation = quaternion;
return go;
}
public void DestoryPool(GameObject go)
{
if (pool.ContainsKey(go.name))
{
pool[go.name].Add(go);
}
else
{
pool.Add(go.name, new List<GameObject>());
pool[go.name].Add(go);
}
go.SetActive(false);
go.transform.SetParent(transform);
}
}
边栏推荐
猜你喜欢
随机推荐
五、请求处理—Rest映射是怎样实现的?
每日一题-最长有效括号-0724
CH32V307 LwIP移植使用
“元宇宙”是个啥?都有哪些大招?
八、请求处理之自定义类型参数绑定原理
手把手教你搭建小程序
《基于机器视觉测量系统的工业在线检测研究》论文笔记
网络ID,广播地址,掩码位数计算
Leetcode刷题——对链表进行插入排序
CVPR2020 - 自校准卷积
C语言联合体union占用空间大小问题
「实用」运维新手一定不能错过的17 个技巧
常见的 PoE 错误和解决方案
LeetCode刷题之第416题
论那些给得出高薪的游戏公司底气到底在哪里?
ACL 的一点心得
LeetCode刷题之第33题
每日一题-寻找两个正序数组的中位数-0713
CAN、CAN FD
【UiPath2022+C#】UiPath控制流程概述