【游戏引擎架构】6.2 资源管理器
资源管理器可以分为离线部分系统和运行时系统
文章目录
- 离线资源管理
- 数据库
- 资产管道
- 运行时资源管理
- 文件结构
- 内存管理
- 文件间引用
离线资源管理
数据库
UE的数据库可以直接浏览、编辑资产,看到运行时的状态;但也存在两个较大的缺点:
- 版本管理不友好。资产以二进制的大文件存储,无法直接使用版本管理工具比对差异。虽然引擎本身对P4做了diff蓝图的支持,但蓝图以外的内容或者不使用p4进行版本管理的团队还是无法对资产作差
- 移动文件有残留。移动文件时会在原来的位置留下一个重定向文件。虽然这种设计可以使得引用链上游的资产不需要更改指向,但会导致冗余数据的留存。对此UE也设计了删除这个中间文件的按钮(位于右键菜单中),不过目前UE4应该还需要手动清理
资产管道
用于将第三方工具创建出来的资产导入引擎使用
资产管道的处理通常分为导出、编译和链接:
- 导出
从第三方工具导出成磁盘上存储的内容 - 编译
经过编译的步骤转化为目标引擎可以识别的格式 - 链接
把资产之间的引用关系链接起来
运行时资源管理
文件结构
可以已有的或自定义文件结构存储。但在进行文件结构设计时,进行打包和压缩有助于加速资源 的加载
- 打包:
建议打包是因为这种存储方式可以加快文件的读取
文件读取的耗时大头可分为三个部分:- 寻道时间
- 开启文件的时间
- 读取文件的时间
将n个资源打包成1个 可以减少上述步骤2:开启文件的耗时
可以参考UE将多个资源文件打成一个pak的方式
- 压缩:
压缩资源文件可以加快资源的传输,由于蓝光光盘/DVD等存储媒介数据传输极慢,压缩的加载提升尤为明显
内存管理
需要考虑如何进行内存管理可以最大化内存利用率、减少内存碎片
内存的分配策略可分为以下几种:
- 堆分配:最简单粗暴的方式,引擎层完全不考虑内存碎片的存在。依赖操作系统的虚拟分页对内存碎片的映射来解决。但这种方式不适用于虚拟分页做得不太好的主机平台
- 堆栈分配:不会产生内存碎片的分配方式。使用单个或者双栈来进行内存的分配
单栈:内存单向增长,以关卡为单位分配、入栈和出栈。适合以关卡为单位进行的游戏
双栈:分为上下两个栈,上面的栈内存自上而下增长,下面的栈内存自下而上增长。双栈的设计可用于不同的分工,如一个栈存放常驻内存的资源,另一个存放临时资源。或者一个用于当前正在展示的内容,另一个用于即将使用的内容,实现一个缓冲策略等等 - 池分配:设定一个固定的块大小,作为内存分配的基本单位。使用链表串联一个资源的各个块。优点是灵活性和适用度较高;缺点是为了填充成完整块,容易造成资源浪费
- 资源组分配:基于池分配器做了一点改进,解决池分配的缺点。
使用一个链表将所有填充的部分串联起来,需要使用内存的时候从这里查找。但资源组分配的缺点是需要复杂度较高,而且需要考虑生命周期的问题:原资源释放的时候会造成使用其填充内存的资源被部分释放。书中提到了一个解决方案是保证原资源的生命周期>=填充资源的生命周期。比如,一个关卡内部的资源就可以使用这个关卡的填充内存。 - 资源文件分段分配:将资源文件根据生命周期或者使用场景划分为不同的段,分给不同的时机加载。
比如UE4在游戏启动的时候只加载pak文件的头部路径信息,而不真正将所有资源加载到内存。(UE5拆得更彻底,直接将描述信息拆成一个单独的文件.utoc和真正存储资产内容的.uasset)使用到的时候才读取资源部分
文件间引用
存取得时候需要处理引用关系尤其是指针的存取。因为指针实际上只是一个内存地址,程序终止以后这个地址就没有意义了。
但我们需要把内容存储到磁盘上,因此不能直接存此时指针的内容而是需要做一个转换。
转换的方式可以是转为存储GUID或者偏移量
- 存储GUID
Global Unique Identifier 全局唯一标识符,每个资源管理系统都应该设计的资源唯一标识 - 存储偏移量
如果存储的是偏移量,需要另外存储一个指针转换表来进行映射
此外还需要考虑C++的对象引用。对于此书中提出两个解决方案:1. 二进制文件不使用C++对象 2. 使用一个表来映射C++对象的偏移量和其所属的类
最后由于存在文件之间的交叉引用,读取的时候,先将所有的引用内容全部反序列化回内存,再将所有的指针转回内存地址
相关文章:
【游戏引擎架构】6.2 资源管理器
资源管理器可以分为离线部分系统和运行时系统 文章目录 离线资源管理数据库资产管道 运行时资源管理文件结构内存管理文件间引用 离线资源管理 数据库 UE的数据库可以直接浏览、编辑资产,看到运行时的状态;但也存在两个较大的缺点: 版本管…...
spring的ThreadPoolTaskExecutor装饰器传递调用线程信息给线程池中的线程
概述 需求是想在线程池执行任务的时候,在开始前将调用线程的信息传到子线程中,在子线程完成后,再清除传入的数据。 下面使用了spring的ThreadPoolTaskExecutor来实现这个需求. ThreadPoolTaskExecutor 在jdk中使用的是ThreadPoolExecutor…...
转载 - 洞察问题本质,解决工作难题
作者:关苏哲 高效管理者的三大技能 问题界定的6个问题 1.你所需要解决的问题是什么? 2.你为什么需要解决这个问题? 3.你期待的理想结果是什么? 4.这个问题包括哪些子问题? 5.你曾经尝试过哪些解决方式?…...
关于计算机找不到d3dx9_43.dll,无法继续执行代码修复方法
d3dx9_43.dll是一个动态链接库文件,它是DirectX的一个组件,主要用于处理游戏中的图形、声音等多媒体元素。当这个文件丢失时,可能会导致以下问题: 1. 游戏无法正常运行:由于d3dx9_43.dll负责处理游戏中的多媒体元素&a…...
《从零开始的Java世界》01基本程序设计
《从零开始的Java世界》系列主要讲解Javase部分,从最简单的程序设计到面向对象编程,再到异常处理、常用API的使用,最后到注解、反射,涵盖Java基础所需的所有知识点。学习者应该从学会如何使用,到知道其实现原理全方位式…...
【数据开发】数据全栈知识架构,数据(平台、开发、管理、分析)
文章目录 一、数据全栈知识架构1、数据方法(思维,统计学,实践,北极星)2、数据工具:数据仓库3、数据规范 二、数据分析工具1、大数据平台2、数据开发:入库计算(重点)3、数…...
基于STM32的宠物托运智能控制系统的设计(第十七届研电赛)
一、功能介绍 使用STM32作为主控设备,通过DHT11温湿度传感器、多合一空气质量检测传感器以及压力传感器对宠物的托运环境中的温湿度、二氧化碳浓度和食物与水的重量进行采集,将采集到的信息在本地LCD显示屏上显示,同时,使用4G模块…...
数据结构的奇妙世界:实用算法与实际应用
文章目录 数据结构和算法的基本概念数据结构数组链表栈队列树图 算法 常见的数据结构和算法排序算法快速排序示例 数据结构的应用数据库管理系统图像处理网络路由 数据结构和算法的性能分析时间复杂度空间复杂度 如何更好地编写代码避免常见错误结论 🎉欢迎来到数据…...
uniapp实现表格冻结
效果图如下: 思路: 1.由于APP项目需要,起初想去插件市场直接找现成的,结果找了很久没找到合适的(有的不支持vue2有的不能都支持APP和小程序) 2.后来,就只能去改uni-table源码了,因…...
Spring面试题11:什么是Spring的依赖注入
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的依赖注入 依赖注入(Dependency Injection)是Spring框架的一个核心特性,它是指通过外部容器将对象的依赖关系注入到对象中,从而…...
用于设计 CNN 的 7 种不同卷积
一 说明 最近对CNN架构的研究包括许多不同的卷积变体,这让我在阅读这些论文时感到困惑。我认为通过一些更流行的卷积变体的精确定义,效果和用例(在计算机视觉和深度学习中)是值得的。这些变体旨在保存参数计数、增强推理并利用目标…...
备受以太坊基金会青睐的 Hexlink,构建亿级用户涌入 Web3的入口
早在2021年9月,以太坊创始人Vitalik Buterin就曾提出了EIP-4337(账户抽象)提案,并在去年10月对该提案进一步更新,引发行业的进一步关注。在今年3月,EIP-4337提案正式通过审计,并成为了ERC-4337标…...
合约升级标准 ERC2535 的设计解析和不足
合约升级标准 ERC2535 的设计解析和不足 Safful最近审计了钻石标准的一份实现代码,这一标准是一种新的可升级合约模式。撰写标准是一项值得赞许的事业,但钻石标准及其实现有许多引人担忧的地方。这份代码是过度工程的产物,附带了许多不必要的…...
【Vue】ElementUI实现登录注册
一、搭建项目 二、后台交互 三、CORS跨域 好啦今天到这了,希望能帮到你!!!...
linux 安装 wordpress
文章目录 linux 安装 wordpress1. wordpress 简介2. wordpress功能和特点3. 部署要求4. 环境搭建4.1 部署 nginx4.1.1 新增配置文件 4.2 部署 PHP74.2.1 查看当前版本4.2.2 YUM 安装 PHP74.2.3 查看 PHP 版本4.2.4 启动PHP-FPM4.2.5 修改配置文件4.2.6 重启服务 4.3 部署 mysql…...
LeetCode902最大为 N 的数字组合(相关话题:数位DP问题,递归遍历和减枝)
目录 题目描述 方法一递归遍历和减枝 方法二动态规划 数位DP问题拓展 通用方法论引入 <...
USB总线-Linux内核USB3.0主机控制器驱动框架分析(十二)
1.概述 如下图所示,Linux内核中USB主机体系结构由五部分组成,分别为Application Software、USB Class Driver、USB Core(USB Driver)、USB Host Controller Driver、USB Host Controller。应用程序处于用户空间,通过系统调用访问Class Drive…...
SQL模板-用户留存率计算
在这段实习中,我遇到了用户留存率计算的需求,这里做个总结。 首先来讲下,什么是用户留存? 在互联网行业中,用户在某段时间内开始使用应用,经过一段时间后,仍然继续使用该应用的用户。用户留存一…...
LeakCanary 源码详解(3)
上一篇:LeakCanary源码详解(2) 如果你是直接刷到这篇的,建议还是从1开始看,然后2,然后是这篇3,如果你只关注这篇的重点hprof 文件定位泄漏位置的感兴趣,可以试试直接读这篇ÿ…...
springboot使用SSE
1、pom文件 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 2、前端代码 <!DOCTYPE html> <html lang"en"> <head><meta ch…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
