尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Unity 构建序列化:level0、sharedassets、resources.assets
一、构建产物总览以 Windows Standalone 为例MyGame_Data/目录大致如下Android 位于assets/bin/Data/MyGame_Data/ ├── globalgamemanagers # 全局管理器PlayerSettings、TagManager、QualitySettings…… ├── globalgamemanagers.assets # 全局管理器引用的资源Always Included Shaders、Splash、MonoScript 等 ├── level0 # Build Settings 中第 0 个场景的场景对象 ├── level1 ├── ... ├── sharedassets0.assets # level0 首次引用的资源对象 ├── sharedassets0.assets.resS # 对应的大块二进制数据纹理像素、网格顶点等 ├── sharedassets0.resource # 音视频数据AudioClip、VideoClip ├── sharedassets1.assets ├── ... ├── resources.assets # Resources 文件夹中的资源及其依赖 ├── resources.assets.resS ├── resources.resource ├── Resources/ │ ├── unity default resources # 内置资源默认字体、内置 Mesh 等 │ └── unity_builtin_extra # 内置 Shader、Default-Material 等 └── Managed/ # 托管程序集Mono 后端或 il2cpp_data这些文件除.resS/.resource外都是同一种格式SerializedFile。区别只在于装了哪些对象。二、三类文件各装什么1. levelN —— 场景本身对应 Build Settings 中第 N 个场景只包含属于场景的对象场景中所有GameObject、Transform以及各类ComponentMonoBehaviour、MeshRenderer、Collider……场景级设置RenderSettings、LightmapSettings、NavMeshSettings、OcclusionCullingSettings场景实例化的 Prefab 会被展开成普通 GameObject 写入Player 中不存在Prefab 实例概念不包含Texture、Mesh、Material、AudioClip、AnimationClip 等资源对象——它们只以引用形式PPtr出现在 level 文件中。2. sharedassetsN.assets —— 场景依赖的资源规则可以概括为按场景构建顺序资源放进第一个引用它的场景所对应的 sharedassets 文件中后续场景复用不重复存储。Scene0 引用: TexA, MatA, MeshA → sharedassets0: TexA, MatA, MeshA Scene1 引用: TexA, TexB → sharedassets1: TexB (TexA 引用 sharedassets0) Scene2 引用: MatA, MeshC → sharedassets2: MeshC (MatA 引用 sharedassets0)因此加载level2时运行时需要同时访问sharedassets2和sharedassets0通过外部引用表。level0 的依赖越多sharedassets0 越大首场景加载越慢——这是用一个极简启动场景做 level0的直接原因。3. resources.assets —— Resources 文件夹所有位于任意Resources/目录下的资源无条件打入不管有没有被引用。这些资源的依赖如 Prefab 引用的 Material、Texture也会被收集进来若某依赖已在其他序列化文件中则可能以跨文件引用的方式指向它具体分配策略随 Unity 版本略有差异建议用下文的 BuildReport 实际核对。Resources 的路径 → 对象索引表保存在globalgamemanagers的ResourceManager中启动时会构建查找结构Resources 中对象越多启动开销越大。这也是官方不推荐大量使用 Resources 的主要原因之一。4. .resS 与 .resource —— 流式数据Unity 5.x 之后大块数据从 SerializedFile 中剥离文件内容说明.assets.resS纹理像素、网格顶点/索引等对象内只存StreamingInfo { offset, size, path }.resourceAudioClip、VideoClip 数据支持流式读取音频好处是SerializedFile 本体小、反序列化快大数据可异步/直接读取到 GPU 上传缓冲Texture Streaming 也基于此机制。三、SerializedFile 二进制结构┌───────────────────────────────┐ │ Header │ metadataSize, fileSize, version, │ │ dataOffset, endianness ├───────────────────────────────┤ │ Metadata │ │ ├─ Unity 版本字符串 │ 如 2022.3.20f1 │ ├─ 目标平台 (BuildTarget) │ │ ├─ enableTypeTree 标志 │ │ ├─ Types[] │ classID、是否被裁剪、脚本类型索引、 │ │ │ 类型哈希、(可选) TypeTree 节点 │ ├─ Objects[] │ PathID(int64)、byteStart、byteSize、typeIndex │ ├─ ScriptTypes[] │ 引用的脚本对象 │ ├─ Externals[] │ 外部文件表GUID、type、pathName │ └─ RefTypes[] / UserInfo │ (SerializeReference 等新版本) ├───────────────────────────────┤ │ Object Data │ 每个对象按 Transfer 顺序二进制写入 │ │ 对象间按 8/16 字节对齐 └───────────────────────────────┘关键点① 跨文件引用PPtr任何对UnityEngine.Object的引用在磁盘上都是PPtr { int m_FileID; int64 m_PathID; }m_FileID 0同一文件内的对象m_FileID nExternals[n-1]指向的文件如sharedassets0.assets、unity default resourcesm_PathID目标文件中对象的唯一标识Player 构建时通常会重新编号与编辑器 YAML 中的 fileID 不同所以 level1 里的 MeshRenderer 指向 sharedassets0 里的 Material就是一个FileID1, PathIDxx的 PPtr。② TypeTreeTypeTree 描述字段布局名字、类型、大小、对齐用于版本兼容的反序列化。Player 构建默认不写 TypeTree引擎与数据版本完全一致直接按编译期布局读取省空间、更快。AssetBundle 默认写入 TypeTree因为可能被不同版本的 Player 加载可用BuildAssetBundleOptions.DisableWriteTypeTree关闭。③ 对象数据写入引擎使用StreamedBinaryWrite调用每个类型的Transfer()基本类型按小端直接写入bool/byte后按 4 字节对齐数组/字符串先写int32长度再写元素结束后 4 字节对齐MonoBehaviourclassID 114先写引擎字段m_GameObject、m_Enabled、m_Script等再按 C# 序列化规则写用户字段四、构建流程中的序列化步骤逻辑上BuildPipeline.BuildPlayer的流程大致是1. 编译脚本Player 版本去掉 UNITY_EDITOR 代码 2. 按 Build Settings 顺序处理每个场景 a. 打开场景执行 IProcessSceneWithReport / OnProcessScene 回调 b. 剥离 EditorOnly 标签对象、HideFlags.DontSaveInBuild 对象 c. 计算依赖闭包 d. 场景对象 → levelN 未分配过的依赖资源 → sharedassetsN大数据 → .resS / .resource 3. 收集 Resources 文件夹 → resources.assets 4. 全局管理器 → globalgamemanagers其引用资源 → globalgamemanagers.assets 5. Shader 变体编译、纹理平台格式转换结果缓存于 Library 6. 可选LZ4 压缩打包为 data.unity3dStandalone 或合并为 .dataWebGL、放入 APK/AABAndroid注意资源在写入时已是平台格式如 ASTC、ETC2、BC7Material 只保留目标平台需要的 keyword 和 Shader 变体引用。五、如何查看谁进了哪个文件方法 1BuildReport API最权威usingUnityEditor;usingUnityEditor.Build.Reporting;usingUnityEngine;usingSystem.Linq;publicstaticclassBuildContentDumper{[MenuItem(Tools/Build And Dump Content)]publicstaticvoidBuildAndDump(){varoptionsnewBuildPlayerOptions{scenesEditorBuildSettings.scenes.Where(ss.enabled).Select(ss.path).ToArray(),locationPathNameBuild/MyGame.exe,targetBuildTarget.StandaloneWindows64,optionsBuildOptions.None};BuildReportreportBuildPipeline.BuildPlayer(options);foreach(PackedAssetspackedinreport.packedAssets){Debug.Log(${packed.shortPath}({packed.overhead}bytes overhead) );foreach(varginpacked.contents.GroupBy(cc.sourceAssetPath).OrderByDescending(gg.Sum(c(long)c.packedSize))){longsizeg.Sum(c(long)c.packedSize);Debug.Log(${size/1024f:F1}KB{g.Key});}}}}packedAssets会精确列出level0、sharedassets0.assets、resources.assets等每个文件中包含的源资源及大小。方法 2Editor.log构建完成后在 Editor.log 中搜索Build Report可看到按类别统计的大小和最大资源列表。方法 3解析构建产物AssetStudio / AssetRipper可视化浏览 SerializedFile 中的对象。UnityPyPythonimportUnityPy envUnityPy.load(MyGame_Data/sharedassets0.assets)forobjinenv.objects:print(obj.path_id,obj.type.name,obj.byte_size)注意由于 Player 构建不含 TypeTree第三方工具需要匹配对应 Unity 版本的类型结构才能完整解析。六、实践建议问题原因对策首场景加载慢level0 依赖多sharedassets0 庞大level0 用极简启动场景再异步加载主场景启动时间长Resources 索引在启动时构建减少 Resources 使用改用 Addressables / AssetBundle包体臃肿Resources 中的资源无条件打包清理 Resources 中无用资源资源重复同一资源在 Player 和 AssetBundle 中各存一份Player 与 Bundle 之间不会去重需规划好资源归属意外包含编辑器资源场景中残留调试对象使用 EditorOnly 标签或IProcessSceneWithReport剥离内置资源冗余引用 Default-Material、内置 Shader用自定义资源替代避免依赖 unity_builtin_extra七、小结levelN第 N 个场景的场景对象GameObject/Component/场景设置。sharedassetsN.assets按场景顺序首次引用即归属的资源跨场景通过 PPtr 共享不重复存储。resources.assetsResources 文件夹中的全部资源无条件打包并影响启动时间。.resS / .resource从对象中剥离的大块数据支持流式读取。所有文件共享 SerializedFile 格式通过Externals 表 PPtr(FileID, PathID)构成跨文件引用网络。理解这套机制后就能有针对性地优化首场景加载、启动时间和包体大小也更容易判断何时应迁移到 Addressables/AssetBundle 体系。
RELATED

相关推荐

从裸机到内核:操作系统实验核心机制与避坑实战

从裸机到内核:操作系统实验核心机制与避坑实战

简介:哈工大操作系统实验配套资料,面向正在学习操作系统原理、需要完成李治军教授实验课程的学生。压缩包共245个文件,约21.89MB,以c源文件、h头文件、o目标文件及makefile构建脚本为主,含内核编译所需的静态库与汇编启…

📅 2026/10/18 1:57:04
Mhvtl虚拟带库+TSM搭建Oracle Rman备份与异机恢复实战

Mhvtl虚拟带库+TSM搭建Oracle Rman备份与异机恢复实战

简介:面向企业级备份与容灾建设场景,这份原创测试文档围绕 TSM6.3、Mhvtl、Oracle 与 DB2 组合,提供了从虚拟带库搭建到数据库恢复的完整实操路径。资源包仅含 1 个 docx 文档,约 1.83MB,但目录结构非常完整&#xff0…

📅 2026/10/18 1:57:04
IDEA中Tomcat启动成功但页面404的三大根源与修复

IDEA中Tomcat启动成功但页面404的三大根源与修复

简介:本资源是一份针对 IntelliJ IDEA 导入 JavaWeb 项目后 Tomcat 启动正常但访问报 404 错误的专项排错指南,面向 Java Web 初学者及从 Eclipse 迁移至 IDEA 的开发者。内容聚焦于 IDEA 自动创建 webapp 导致 WEB-INF/web.xml 被清空、项目上下文路径配…

📅 2026/10/18 1:57:04
MORE NEWS

更多资讯

📰

回归预测可视化指南:用sklearn和matplotlib绘制真实值与预测值对比图

回归模型跑完之后,很多人第一件事就是看R和MSE,数字漂亮就认为万事大吉。但我一直觉得,指标只是结果的高度浓缩,真正能暴露模型问题的,是把测试集真实值和模型预测值画在同一张图上,看曲线走势、看偏差分布…

📰

m3u8下载实战:ffmpeg与AES-128解密及防坑指南

简介:一款面向流媒体爱好者的m3u8在线下载与提取工具,基于Python编写,用户只需提供M3U8链接,工具即可自动拉取全部TS分片,并借助ffmpeg合并为完整视频文件。工具采用多线程机制提升下载速度,适合需要离线观…

📰

jsPlumb + jQuery 流程图设计器实战:拖拽连线与拓扑保存

简介:这是一份面向Web前端开发者与流程设计初学者的jsPlumbjQuery流程图设计实例资源,重点解决在网页中快速搭建可拖拽、可连线、可交互的流程图这一常见需求。压缩包共216个文件,约984KB,以148张png截图、24个js脚本、20个gif动图…

📰

Spring Bones弹簧骨骼快速指南:让Blender的头发和尾巴自然甩起来

Spring Bones弹簧骨骼快速指南:让Blender的头发和尾巴自然甩起来 【免费下载链接】awesome-blender 🪐 A curated list of awesome Blender addons, tools, tutorials; and 3D resources for everyone. 项目地址: https://gitcode.com/GitHub_Trending…

📰

六模块提示词结构:让大模型输出稳定可用的实操指南

大模型用多了就会发现一个非常扎心的现象:你明明把需求写得清清楚楚,甚至把背景资料都贴全了,结果模型给出的答案还是天马行空、格式混乱,或者干脆自说自话。问题多半不在模型本身,而在于你给的提示词是“散装”的——…

📰

SSM+Vue药品进销存系统设计与实现:从数据库到答辩全指南

刚看到 "2026毕设ssmvue抗新冠肺炎药品进销存管理系统论文程序" 这个题目的时候,我第一反应就是:这又是一个典型的"老技术栈套新业务场景"毕设,技术不难,但业务逻辑绕人。做进销存系统的同学很多,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬