当前位置:网站首页>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);
}
}边栏推荐
猜你喜欢

LeetCode刷题之第55题

偷题——腾讯游戏开发面试问题及解答

基于STM32F407的WIFI通信(使用的是ESP8266模块)

Cocos Creator开发中的事件响应

【UiPath2022+C#】UiPath控制流程概述

Redis集群(docker版)——从原理到实战超详细

LeetCode刷题之第33题

【UiPath2022+C#】UiPath If条件语句
![[Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)](/img/59/ce3e18f32c40a97631f5ac1b53662a.png)
[Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)

GIS面试问题
随机推荐
最简单的防抖节流理解法
C语言入门笔记 —— 函数(1)
每日一题-盛最多水的容器-0716
【ts】typescript高阶:分布式条件类型
栈区中越界可能造成的死循环可能
C语言—三子棋的实现
每日一题-无重复字符的最长子串-0712
常用 crud 的思考和设计
【ts】typescript高阶:联合类型与交叉类型
硬核!Cocos开发面试必备十问,让你offer拿到手软
【ts】typescript高阶:映射类型与keyof
LeetCode刷题之第23题
网管日记:故障网络交换机快速替换方法
LeetCode刷题之第416题
PID详解
Jupyter notebook选择不同的Anaconda环境作为内核运行
tensorflow的session和内存溢出
Unity常用模块设计 : Unity游戏排行榜的制作与优化
【UiPath2022+C#】UiPath数据类型
八、响应处理——ReturnValueHandler匹配返回值处理器并处理返回值原理解析