Unity 构建序列化:level0、sharedassets、resources.assets

发布时间:2026/10/18 1:57:06

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 体系。
延伸阅读

更多相关文章

2026/10/18 1:57:06

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

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

2026/10/18 1:57:06

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

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

2026/10/18 1:57:06

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

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

2026/10/18 3:17:11

Swoole Loader预编译包ABI兼容性指南:5维指纹精准匹配

简介:本资源是面向PHP开发者与运维工程师的Swoole Loader扩展全版本兼容仓库,专为解决不同PHP环境(尤其是旧版及多线程场景)下扩展加载失败、版本错配等部署难题而整理。资源涵盖PHP 5.4至8.1全系列支持,同时提供线程安…

2026/10/18 3:17:11

二进制枚举入门:从位运算到组合搜索的实战指南

1. 二进制枚举到底在解决什么问题1.1 从一个具体场景说起假设你面前有n个开关,每个开关只有“开”和“关”两种状态。现在你想知道,在所有可能的开关组合中,哪些组合能满足某个特定条件——比如“恰好有三个开关是打开的”或者“打开的总功耗…

2026/10/18 3:17:11

无人机航拍巡检数据集之建筑物垃圾识别 yolo航拍垃圾检测 固体废物检测数据集 固体垃圾抛洒识别数据集 垃圾倾倒识别数据集10279期

固体废物检测数据集简介 核心信息总览表信息维度具体内容数据集类别目标检测类,仅包含 “废弃物” 1 个核心类别数据数量共包含 102 张标注图像,单张图像标注框数量最多达 3 个数据集格式种类原始标注为 YoloDarknet 格式的 txt 文件,同时支持…

2026/10/18 3:17:11

装备制造企业SAP实施必须掌握的37个关键决策点

简介:本资源是一份面向装备制造企业中高层管理者、数字化转型负责人及SAP实施顾问的150页专业PPT方案,聚焦智慧化背景下SAP系统驱动的数字化转型路径。针对工程图文档混乱、研产协同低效、工程变更失控、营销服务智能化不足等典型痛点,方案系…

2026/10/18 3:17:11

AutoModel自定义模型保存与加载:从配置注册到实战排查

AutoModel 是 Hugging Face Transformers 里我最常用的类,没有之一。不管是加载别人训练好的开源模型,还是把本地 checkpoint 塞进 pipeline,一句AutoModel.from_pretrained()就搞定了。但等你自己开始训练自定义模型、想用同一套加载逻辑把模…

2026/10/18 3:12:11

WinDbg内核调试原理:KD协议、符号解析与物理内存观测机制

简介:本资源是面向Windows系统开发者、驱动工程师及高级运维人员的Windbg调试工具实战资料包,聚焦内核与用户态程序崩溃分析、内存泄漏定位及蓝屏故障排查等核心场景。压缩包共307个文件,涵盖82个DLL动态库、39个EXE可执行文件、42个H头文件、…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑