对象池的简单应用

2023-10-28


对象池的概念
对象池是个什么东西呢?对象池是用来管理对象的一个池子,当一个物体需要大量的创建和删除时,由于函数Instantiate十分的耗费性能,所以要用对象池来管理,在加载界面中先在池子里面创建一些游戏物体,然后需要的时候从池子里取出,当使用完成后再放回池子里,利用SetActive来代替Instantiate和Destroy。对象池呦三种模式:队列模式,链表模式,栈模式,三种模式大同小异,看个人喜好使用

对象池里只有一个预制体

队列对象池

public GameObject pre;//预制体
private Queue<GameObject> quepool=new Queue<GameObject>();//空池子
public GameObject Creat()
{
  GameObject go=null;
  //如果池子里有对象就把它取出 如果没有再创建
  if(quepool.Count>0)
  {
    go=quepool.Dequeue();
    go.SetActive(true);
    return go;
  }
  return Instantiate(pre);
}
public void Destory(GameObject go)
{
  quepool.Enqueue(go);
  go.SetActive(false);
}

``

对象池里面有多个预制体

思路:让对象池的使用者来提供自己的预制体,让其作为参数来传递给对象池。使用字典来管理(Dictionary)

字典:Dictionary<key , value > key是键 一个key代表一类物体 value是值 (感觉和数据结构中的Map一毛一样)

物体的Id:每一个正在使用的物体的id都是唯一的,物体销毁后id就会失效,由于使用对象池,物体不会被销毁,因此可以使用GetInstanceID来获取物体的ID并使用

创建和销毁的伪代码

创建物体时提供参数prefab,把prefab转为物体种类的ID,判断对象池中是否有这个ID,如果没有则需要将这个类型加入对象池中。将物体返回之前要记录,记录保存在outPool中

销毁物体时要判断是否存在于outPool字典中,如果不存在则它不是从对象池中取出的,如果存在则将他从outPool中删除,添加到pool中

代码

private Dictionary<int , Queue< GameObject >> pool=new Dictionary<int , Queue< GameObject >>();//对象池本身的物体
private Dictionary<GameObject ,int>outPool=new Dictionary<GameObject, int>();//记录离开的物体
//取物体
public GameObject Creat(GameObject prefab)
{
  int id=prefab.GetInstanceID();
  GameObject go=GetForId(id);
  if(go==null)
  {
    go=Instantiate<GameObject>(prefab);
    //不存在键就把他加进去
    if(!pool.ContainKey(id))
    {
      pool.Add(go,new Queue<GameObject>());
    }
  }
  outpool.Add(go,id);
  return go;
}
public GameObject GetForId(int id)
{
  //在池子里寻找物体,如果没有这个id或者id的池子里没有物体 就返回null
  if(!pool.ContainKey(id)||pool[id].Count==0) return null;
  GameObject go=pool[id].Dequeue();//如果里面有就把物体出队
  go.SetActive(true);
  return go;
}
//存物体
public void Destory(GameObject prefab)
{
  if(!outpool.ContainKey(prefab)) return;//输出池子为空说明预制体不存在对象池里面
  int id=outpool[prefab];
  prefab.transform.parent=transform;
  prefab.SetActive(false);
  pool[id].Enqueue(prefab);
  outpool.Remove(go);
}

测试功能

此处测试的为存单个物体的对象池,若测多个物体的则将Pool改为ObjPool即可

做个预制体吧

public Pool pool;//为啥预制体也要设成public?因为要在测试代码中调用它 预制体的public生成后都是空的
要用代码给他们重新赋值
public Pool pool;
void Update()
{
        Vector3 dir = transform.position - Vector3.zero;
        transform.position += dir.normalized * Time.deltaTime * 2;
        if(Vector3.Distance(transform.position,Vector3.zero)>10)
        { 
            pool.Destory(gameObject); 
        }
}

开始测试

public GameObject pre;
Pool pool;
void Start()
{
  pool=GameObject.Find("Pool").GetComponent<Pool>();
}
void Update()
{

  if(Input.GetKeyDown(KeyCode.Space))
  {
    for(int index=0;index<1000;index++)
    {
      GameObject go=pool.Creat();
      go.GetComponent<Pre>().pool=pool; 
      go.transform.position=Random.onUnitSphere*2;//onUnitSphere:返回半径为1.0的球面上的随机点
      go.transform.setparent=transform;
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象池的简单应用 的相关文章

随机推荐

  • 随笔篇----比特的传输

    琐碎的知识又增加了 这是我觉的比较有意思的科普 解开了一些生活中的小疑问 例如 电话 网页 电视 这些信号怎么传递的 人们怎么就成了千里眼 顺风耳 本文目的为 简单科普我们生活周围的信息是如何传递 如果学过通信的朋友可以略过啦哈 关键词 A
  • 软件测试阶段的风险

    1 需求风险 2 测试用例风险 3 缺陷风险 4 代码质量风险 5 测试环境风险 6 测试技术风险 7 回归测试风险 8 沟通协调风险 9 其他不可预计的风险 软件测试常见的风险 主要有以下几点 1 需求风险 对软件需求理解不够准确 导致测
  • pyinstaller打包执行文件报错NameError: name ‘defaultParams‘ is not defined问题解决方案

    老猿Python博文目录 https blog csdn net LaoYuanPython 一 问题 最近在执行以前打包的一个PyQT程序时报错 错误信息如下 F coffeDog videoToGif dist video2Gif gt
  • 本地资源加载不了 file:// net::ERR_UNKNOWN_URL_SCHEME

    本地资源加载不了 file net ERR UNKNOWN URL SCHEME 解决 开发环境使用tsFile 生产环境使用file
  • 用git创建空白分支

    用git创建空白分支 许多时候 需要添加的分支的代码与原来的代码没有一点关系 若是我们创建分支的话 则会继承master原来的东西 此时可以创建一个空白的分支 git checkout orphan test 这个时候会有许多无关文件存在
  • arp攻击实验(一)用一条指令让对方瞬间无法上网

    前言 本实验主要是利用局域网主机在进行2 3层通信时 协议上的漏洞 利用ARP欺骗 造成局域网内主机通信的失败 本文摘自 泰泰博客 www taitaiblog com 更多相关资源可访问该网站 实现原理 其主要原理是局域网内的 攻击机 通
  • centos 7 中的对文件的基本操作

    在文件夹中创造文件 touch 未创建前 在当前文件夹创建后并查看 创造文件夹 mkdir 未创建前 创建之后并查看 如果需要一次创造多个文件夹时 需要用到参数 p 递归创建文件夹 并用命令tree查看文件的结构 文件的复制 cp 复制te
  • [转]OpenSynergy的COQOS Hypervisor SDK-实现仪表和车载信息娱乐系统共享显示

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 声明 本文只用于个人学习交流 若不慎造成侵权 请及时联系我 立即予以改正 锋影 email 174176320 qq com OpenSyn
  • python3[爬虫实战] 使用selenium,xpath爬取京东手机(上)

    当然了 这个任务也是从QQ群里面接过来的 主要是想提升自己的技术 一接过来是很开心的 但是 接完之后 写了又写 昨晚写了3小时 前提晚上写了2小时 搞的有些晚了 搞来搞去就卡在一个地方了 希望懂的大神们多帮忙指点一下 使用selenium
  • chatgpt赋能python:Python重写父类方法:在OOP编程中的应用

    Python重写父类方法 在OOP编程中的应用 在Python的面向对象编程范式中 继承是一种非常重要的概念 当我们声明一个类时 我们可以通过继承来扩展类的功能并避免重复编写代码 在这个过程中 很可能你会碰到需要重写父类方法的情况 本篇文章
  • java输出1-100之间不能被5整除的数,每五个一行

    public class HomeWork06 public static void main String args int count 0 for int i 1 i lt 100 i if i 5 0 System out print
  • 剑指 Offer II 033. 变位词组&剑指 Offer II 035. 最小时间差 -做题总结和心得(剑指offer进阶-哈希表部分)

    剑指 Offer II 033 变位词组 该题解法是hash sort 答案是评论区大佬写的 大体思路 创建一个哈希表 再将每个字符串变成字符数组 排序后若哈希表里不存在排序后的字符串 则创建索引 然后将原字符串放进对应索引的数组里 cla
  • cartographer 代码思想解读(7)-位姿估计器PoseExtrapolator实现

    cartographer 代码思想解读 7 位姿估计器PoseExtrapolator实现 pose extrapolator类定义 插入IMU数据 AddImuData 插入里程计数据 AddOdometryData UpdateVelo
  • Plotly可视化:TypeError: box() got an unexpected keyword argument ‘box_color‘

    一 问题描述 我用Plotly库进行可视化 import plotly express as px category orders month stage month end month middle month start fig px
  • C++ 鼠标点击的获取

    C 鼠标点击 首先一个比较常用的宏定义如下 define KEY DOWN VK NONAME GetAsyncKeyState VK NONAME 0x8000 1 0 使用KEY DOWN 鼠标事件 可以方便获取很多鼠标的事件 鼠标各个
  • 设计模式-----工厂模式

    一 工厂模式简介 工厂模式分为简单工厂模式 工厂方法模式和抽象工厂模式 它们都属于设计模式中的创建型模式 其主要功能都是帮助我们把对象的实例化部分抽取了出来 目的是降低系统中代码耦合度 并且增强了系统的扩展性 二 简单工厂模式 简单工厂模式
  • 【最新】如何降低深度强化学习研究的计算成本(Reducing the Computational Cost of DeepRL)...

    深度强化学习实验室 官网 http www neurondance com 论坛 http deeprl neurondance com 人们普遍认为 将传统强化学习与深度神经网络相结合的深度强化学习研究的巨大增长始于开创性的DQN算法的发
  • C# 对西门子1200PLC 的优化过的DB块进行符号寻址

    最近一直在学习C 一直想利用C 对西门子的PLC的优化DB块进行数据读取 因为S7通讯只支持绝对地址 这样的话 对PLC端编程很不友好 后来发现atvise这个小软件 发现它能够符号寻址西门子PLC 然后通过OPC转发出去 这样的话 我就在
  • 《现代密码学教程》

    第一章 密码学概论 第二章 密码学基础 第三章 古典密码体制 第四章 分组密码 第五章 序列密码 第六章 Hash密码 第七章 公钥密码体制 第八章 数字密码签名 第九章 密码协议 第十章 密钥管理
  • 对象池的简单应用

    对象池呦 对象池里只有一个预制体 队列对象池 对象池里面有多个预制体 创建和销毁的伪代码 代码 测试功能 做个预制体吧 开始测试 对象池的概念 对象池是个什么东西呢 对象池是用来管理对象的一个池子 当一个物体需要大量的创建和删除时 由于函数