对象池简单理解

2023-10-31

unity中一些需要频繁创建和销毁的对象,在销毁时会频繁的调用gc,非常占用cpu时,造成性能瓶颈。这时候就需要对象池技术。使用对象池在销毁时并不调用gc,而是仅仅将需要销毁的obj失活,当再次创建同类对象时,在对象池中查找可以使用的对象进行调用。仅仅在需要的时候调用gc进行一次销毁。这样做大大减少了cpu的压力,但是增大了内存的消耗,通常情况这种牺牲是值得的。

对象池的数据情况:



一个简单对象池类的实现:

public class GameObjectPool : MonoSingleton<GameObjectPool>
{
    //字典的记录:一个种类
    //List:该类别的多个对象
    private Dictionary<string, List<GameObject>> cache;

    public override void Init()
    {
        base.Init();

        cache = new Dictionary<string, List<GameObject>>();
    }

    /// <summary>
    /// 通过对象池创建对象
    /// </summary>
    /// <param name="key">对象的种类</param>
    /// <param name="prefab">对象的预制件</param>
    /// <param name="pos">位置</param>
    /// <param name="dir">旋转方向</param>
    /// <returns>游戏对象</returns>
    public GameObject CreateObject(string key, GameObject prefab, Vector3 pos, Quaternion dir)
    {
        //查找可以使用的对象
        GameObject go = FindUsableObject(key);

        //如果没有则创建
        if (go == null)
        {
            //创建
            go = Instantiate(prefab);
            //添加到池中
            Add(key, go);
        }

        //使用对象
        UsabObject(pos, dir, go);
        
        return go;
    }

    private void UsabObject(Vector3 pos, Quaternion dir, GameObject go)
    {
        go.transform.position = pos;
        go.transform.rotation = dir;
        go.SetActive(true);//启用
    }

    private void Add(string key, GameObject go)
    {
        //如果池中没有键  则 添加记录
        if (!cache.ContainsKey(key)) cache.Add(key, new List<GameObject>());
        cache[key].Add(go);
    }

    private GameObject FindUsableObject(string key)
    { 
        return cache.ContainsKey(key) ? cache[key].Find(o => !o.activeInHierarchy) : null;
    }

    /// <summary>
    /// 即时回收游戏对象
    /// </summary>
    /// <param name="go">游戏对象</param>
    public void CollectObject(GameObject go)
    {
        go.SetActive(false);
    }

    /// <summary>
    /// 延时回收游戏对象
    /// </summary>
    /// <param name="go">游戏对象</param>
    /// <param name="delay">延迟时间</param>
    public void CollectObject(GameObject go,float delay)
    {
        StartCoroutine(DelayCollect(go,delay));
    }

    private IEnumerator DelayCollect(GameObject go, float delay)
    {
        yield return new WaitForSeconds(delay);
        go.SetActive(false);
    }

    public void Clear(string key)
    {
        //销毁列表中的游戏对象
        foreach (var item in cache[key])
        {
            Destroy(item);
        }
        //移除字典中的记录
        cache.Remove(key);
    }

    public void Clear()
    { //删除字典中所有记录
        //1.将所有键存入列表
        List<string> keys = new List<string>(cache.Keys);
        //2.遍历列表
        foreach (var item in keys)
        {
            //3.删除 字典 记录
            Clear(item);
        }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象池简单理解 的相关文章

  • IIS应用程序池回收+quartz调度

    我正在 IIS 7 5 上运行一个 Web 应用程序 它需要偶尔回收 否则内存使用情况会失控 这是我正在研究的问题 当它回收时 它实际上不会运行 直到另一个请求到来 而quartz不会运行 有没有办法让IIS在回收应用程序池后立即自动启动1
  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 在 Java 中创建 T 的新实例

    在C 中 我们可以定义一个泛型class A
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 使用 LINQ 更新 IEnumerable 对象的简单方法

    假设我有一个这样的业务对象 class Employee public string name public int id public string desgination public int grade List
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐

  • python 查找指定字符在字符串中的次数(全)

    s neu is very neupk kjneuneu dhsj neu print s count neu n 0 co 0 while s find neu n len s 1 co 1 n s find neu n len s 1
  • 【技术经验分享】计算机毕业设计hadoop+spark知识图谱房源推荐系统 房价预测系统 房源数据分析 房源可视化 房源大数据大屏 大数据毕业设计 机器学习

    创新点 1 支付宝沙箱支付 2 支付邮箱通知 JavaMail 3 短信验证码修改密码 4 知识图谱 5 四种推荐算法 协同过滤基于用户 物品 SVD混合神经网络 MLP深度学习模型 6 线性回归算法预测房价 7 Python爬虫采集链家数
  • 实现线程同步的几种方法

    在多线程程序中 会出现多个线程抢占一个资源的情况 这时间有可能会造成冲突 也就是一个线程可能还没来得及将更改的 资源保存 另一个线程的更改就开始了 可能造成数据不一致 因此引入多线程同步 也就是说多个线程只能一个对共享的资源进行更改 其他线
  • 计算机用户名携带中文路径,Win10 User下的中文用户名改成英文路径操作方法

    导读 Win10 User下的中文用户名改成英文路径的方法 相关电脑教程分享 有很多Win10系统用户在新购买电脑或是新装Win10时采用了中文用户名 这时会发现C User下的文件夹是中文名 但是这样有一个很不好的地方 很多软件安装在个路
  • JavaWeb新留言板系统 23年4月原创

    JavaWeb留言板系统 2023年4月原创 极低价付费提供项目代码 sql文件 配置说明 包运行服务 答疑解惑服务 私信即可 功能概述 JavaWeb留言板系统项目遵循MVC编程模式 基于Servlet Bootstrap MySQL J
  • Git&&Github配置

    1 把现有的 ssh key 都删掉或查找现有的key PS 如果多打空格可能要破环系统 删掉现有的Key rm rf ssh 查找现有的Key 如果没有 bash终端显示如下 No such file or directory 如果已经存
  • 常见Windows Server漏洞处理方法

    常见的几种漏洞 mysql 3306 Oracle 1521 Redis 6379 Tomcat 8080 445 138端口不安全 weblogic Server 7001 3389远程桌面 下面分别讲解几种漏洞解决的方法 一 mysql
  • CH06_第一组重构(下)

    封装变量 Encapsulate Variable 132 曾用名 自封装字段 Self Encapsulate Field 曾用名 封装字段 Encapsulate Field let defaultOwner firstName Mar
  • C++的强制类型转换

    关于强制类型转换的问题 很多书都讨论过 写的最详细的是C 之父的 C 的设计和演化 最好的解决方法就是不要使用C风格的强制类型转换 而是使用标准C 的类型转换符 static cast dynamic cast 标准C 中有四个类型转换符
  • 在docker上安装spark

    拉安装好spark的镜像 https hub docker com r bde2020 spark master docker pull bde2020 spark master 安装master节点 docker run name spa
  • SpringBoot 整合shiro框架

    网上有很多整合shiro的博客分享 但是貌似没找到一个完整 并且能够实现的 不是包的问题 就是代码的问题 也可能是自己的问题 或者版本的问题 所以 整理了一版自己已应用的 maven依赖
  • Netty 入门实战

    Netty 入门实战 异步事件驱动的Java开源网络应用程序框架 用于快速开发可维护的高性能协议服务器和客户端 Netty 项目旨在为可维护的高性能和高可伸缩性协议服务器和客户端的快速开发提供一个异步事件驱动的网络应用框架和工具 Netty
  • Kafka概述

    Kafka概述 Kafka 基础架构 生产者消息发送流程 生产者发送消息示例 分区的好处 生产者如何提高吞吐量 可靠性总结 幂等性问题 Kafka 事务 生产者乱序问题 kafka是一个多分区 多副本且基于zookeeper协调的分布式消息
  • wsl连接vscode

    文章目录 1 wsl 安装 2 wsl搭配vscode 3 adb 在wsl上的使用 1 wsl 安装 由于我已经提前安装了 所以这里没办法展示如何安装 大致有两个需要注意的点 在官网或者其它博文有 1 需要在命令行输入安装命令 2 需要下
  • python-循环

    文章目录 循环 是什么 定义 分类 做什么 怎么用 语法 If 语法 If 基本语法 If else if elif else 结构 if 嵌套 while 语法 while 基本语法 while else while else break
  • 费曼学习法简述

    你真的已经对某个知识点足够深入了吗 还是只是停留在一个肤浅的阶段 不妨试试费曼学习法 让自己的思考更加深入 费曼学习法 主要分为四个阶段 下面针对这四个步骤进行详述 选择概念 选择一个你想学习的概念 讲授概念 你对面的是一个10岁孩童 试图
  • 操作系统复习知识点(第四章、第五章)

    存储器管理 1 多层结构的存储器系统 存储器的多层结构 存储层次至少应具有三级 最高层为 CPU 寄存器 中间为主存 最底层是辅存 还可以根据具体的功能分工细划为寄存器 高速缓存 主存储器 磁盘缓存 固定磁盘 可移动存储介质等 6 层 在存
  • Mad Scientist (纯模拟题)

    Mad Scientist 题目描述 Farmer John s cousin Ben happens to be a mad scientist Normally this creates a good bit of friction a
  • QT--3.创建一个简单的图形界面

    创建一个简单的图形界面 1 qt基础 qt的移植性非常强 2 做一个简单的qt界面 1 创建一个工程 2 项目选择Application 然后选择Qt Widgets Application 最后选择choose 注意 创建项目的名称和路径
  • 对象池简单理解

    unity中一些需要频繁创建和销毁的对象 在销毁时会频繁的调用gc 非常占用cpu时 造成性能瓶颈 这时候就需要对象池技术 使用对象池在销毁时并不调用gc 而是仅仅将需要销毁的obj失活 当再次创建同类对象时 在对象池中查找可以使用的对象进