Unity 配置技巧:内存、音频和纹理





5.00/5 (1投票)
本博客涵盖了一些关于内存优化以及使用纹理的技巧和窍门,由 Steve Hughes 汇编,他在英特尔担任视觉计算应用工程师。
英特尔® 开发者专区 提供了跨平台应用开发、平台和技术信息、代码示例和同行专业知识的工具和操作指南,以帮助开发人员创新和取得成功。 加入我们的社区,获取关于 Android、物联网、英特尔® RealSense™ 技术和 Windows 的资源,下载工具、访问开发套件、与志同道合的开发者分享想法,并参与黑客马拉松、竞赛、路演和本地活动。
本博客涵盖了一些关于内存优化以及使用纹理的技巧和窍门,由英特尔视觉计算应用工程师 Steve Hughes 汇编。 欲了解更多信息,请参阅 Steve 和 Cristiano 的文章(大多数技巧也适用于 Windows 和 Android)以及我的 使用 Unity 和 Intel® RealSense™ SDK 的技巧。
使用纹理
- 除非确实需要,否则不要为纹理创建 Mipmap
- 使用压缩纹理
- 除非需要,否则不要将纹理设置为可读 (CPU 读/写)。 这可以避免额外的 CPU 复制、标记等。
- 根据屏幕分辨率减小纹理大小
- 安卓 & 小屏幕
- 关于模型 - 跳过顶层 MIP (质量设置>渲染>纹理质量)
- 将 RGB(可压缩)与 Alpha(不可压缩)通道分离
设计技巧
- 法线贴图不需要与漫反射贴图 1:1 缩放。
- 从动画中删除多余的关键帧(仅刷新以更改图形)
对于网格模型
- 从网格中删除未使用的通道(在 Player 设置下,启用优化网格数据)
- 对于低 RAM 系统的详细网格,将质量设置为使用 maxLOD
有关在 Unity 中优化图形的更多信息,请参阅:如何使用 Unity 规划优化
音频
- 利用 200k 缓冲区进行音频播放
- 将短片段未压缩加载到此缓冲区中
- 或者使用
AudioClip.GetData
进行解压缩,然后释放压缩后的片段
内存优化
- 两种查看正在消耗 RAM 的方法
Profiler.GetRuntimeMemorySize()
可以找到高 RAM 消耗对象(建议输出到调试日志)- 在 Mono 的 CIL(通用中间语言)中查找三种分配类型 - Newarr, Newobj, Box
- 通过在启动时预先分配内存空间(基于资产使用历史记录)来手动扩展堆。
- 对于即时需求,调用
Resources.UnloadAsset
(如果资产仍需要被引用)或使用Resources.UnloadUnusedAssets
(对于未被引用) - 由于 Unity 的自动垃圾回收通常只在堆已满或没有足够大的空闲块时才会被调用,因此请考虑在加载一个级别之前和之后调用 (
System.GC..Collect
)(或者将其放在计时器上)或者在过渡时进行清理。 - 避免使用大量隐藏分配的函数
- 通过使用结构(存储在堆栈上)而不是类(存储在堆上)来避免内存碎片。
- 记住枚举器会分配 RAM。 并且 (Foreach) 被重新处理成一个代码块,它也会分配一个枚举器。
- 出于同样的原因,避免使用匿名方法和 Lambda 表达式。
- 流式传输资产以消耗更少的 RAM,在构建时将相关资产收集到资产包中,然后在运行时流式传输它们。 (务必在下一个场景或资产包流之前销毁它们)。
- 不要将字符串加在一起。 不要逐帧操作字符串(而是添加一个陷阱,以便仅在值更改时才更新它。)
- 使用
StringBuilder
类创建字符串,不要将数组用于返回字符串的函数,因为它会在循环中不断转储和重新分配 - 创建资产池类(子弹/导弹)来存储对象,而不是多个 new-ing - 例如
MyClass m – poolOfMyClass //do stuff poolOfMyClass.Store(m);
致谢: 上述部分材料收集自
有关更多信息,请参阅
- https://software.intel.com/en-us/node/542152(大多数提示也适用于 Windows 和 Android)
- 使用 Unity 和 Intel® RealSense™ SDK 的技巧.