3.4 包体优化与裁剪:每一兆字节都要答辩
核心结论
应用商店对很多地区仍限 100~150MB 下载(超了走分包/按需下载)。移动包体必须当作"钱"来管理:每个资源都要说明自己凭什么占这几兆。Android 的包体瘦身边际收益最高——官方有专门一页讲缩减 Android 包体(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/reducing-android-binary-size-i-20a5),先读它,再做下面这些流程。
包体解剖:钱花在哪了
打包后用 UnrealPak 工具或者引擎的报告查看各目录占用。经验分布:
| 大头 | 占比(典型) | 优先治理 |
|---|---|---|
| 贴图 | 45~60% | ★★★★★ |
| 音频 | 10~20% | ★★★★ |
| 动画 | 5~10% | ★★★ |
| 静态网格 | 5~15% | ★★★ |
| 着色器/材质 | 5~10% | ★★ |
| 其他(字体/UI 等) | 5% | ★ |
治理顺序按占比从大到小,先贴图后一切。
贴图瘦身五板斧
- 降最大尺寸:角色 2048、场景物 1024、小道具 512(见 0303 规范表)。
- 压缩格式选对:Android 用 ASTC(比 ETC 兼容好且质量高),iOS 用 ASTC。注意 ASTC 在老设备(<Android 5.0)不支持,要给降级方案(ETC2)。
- 通道打包:四张灰度图合一(见 0201)。
- 裁 mips:
Texture -> Never Stream与Run-time Virtual Texturing按需勾。 - UI 图集化:散碎小图合并大图,省元数据也省内存。
音频瘦身
- 长音乐用流式播放(Streaming),不一次性载入。
- 音效采样率降到 22050Hz(手机扬声器 听不出 44100 的区别)。
- 格式:过渡用 ADPCM/OGG。
- 裁掉静音段(多数引擎/工具导出时自动,UE 用 SoundCue 的 Trim 或外部工具)。
裁剪:引擎功能做减法
| 裁剪项 | 设置/做法 | 节省 |
|---|---|---|
| 未用插件 | Packaging 时排除非必需插件 | 数十~百 MB |
| 编辑器数据 | 打 Shipping,不打包 Dev/Editor 资产 | 上百 MB |
| 未用目标平台 | 只编目标平台 shader | 显著 |
ini 裁剪 |
[Core.System] 去掉不用的模块 |
小 |
| 字体子集化 | 只包用到的字符集(尤其中文) | 数十 MB |
中文字体是大头:完整中文字体动辄 20~100MB。用
Font Face子集化或在线字体方案,只打进常用 3000~7000 字。
常见坑与解法
坑 1:AAB 打出来比预期大
原因:默认 AAB 里同时带 ARM32/ARM64,shader 多份。
解法:用 ABI split(Google Play 的多 APK)或只保 ARM64(现代机全覆盖)。详见 https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/reducing-android-binary-size-i-20a5。
坑 2:贴图明明是 1024,包里还是占 10MB
原因:mip 全部内嵌 + 无压缩格式。
解法:确认压缩格式(ASTC)、确认开启了 mip streaming、No linger on filesystem 的导出模式。
坑 3:Shader 缓存膨胀
原因:材质一变就重编,shipping 包带了一堆未用 permutation。
解法:开启 Shader Compression;用 PSO Cache(Pipeline State Object 预编译清单),既缩包体又减少首次进入卡顿——这是一举两得的事。
相关节点速查
- 查包内容:
UnrealPak <pakfile> -list(或 Archive 工具) - 平台压缩:
Texture Compression Settings(ASTC) - 字体子集:字体编辑器的
Subset或离线工具
心得:包体优化是"工程师做一次、全团队受益"的投入。我们项目曾经把 1.2GB 的包压到 380MB,多做的事只有:贴图规范+ASTC+字体子集+关插件。省下的每一兆都是买量成本的降低。
