65.9K
CodeProject 正在变化。 阅读更多。
Home

Unity for Intel x86 平台优化指南:第 2 部分

2016年4月15日

CPOL

6分钟阅读

viewsIcon

19236

本指南将探讨两个主要的优化领域:脚本和编辑器。

Intel® Developer Zone 提供跨平台应用程序开发工具和操作指南、平台和技术信息、代码示例以及同行专业知识,帮助开发人员进行创新并取得成功。加入我们的社区,了解 Android物联网Intel® RealSense™ 技术Windows,下载工具,获取开发套件,与志同道合的开发人员交流想法,并参与黑客松、竞赛、路演和本地活动。

目录

返回教程第一部分
适用于 Intel x86 平台的 Unity* 优化指南:第一部分

优化

本指南将探讨两个主要的优化领域:脚本和编辑器。您将看到针对每种优化基于其功能根源的多种具体方法。

脚本优化

脚本视锥剔除和协程

当您分析应用程序性能时,如果发现脚本的 Update() 函数不需要每帧都调用,那么您可以使用几种绝佳的方法来减少更新量。

  • 脚本视锥剔除
    • 使用以下 Monobehavior 回调,可以剔除摄像机视锥外的脚本,这些脚本在不在焦点时不需要更新。
      图 12. 脚本所在对象离开/进入摄像机视锥时触发的 Monobehavior 回调
  • 协程
    • 协程本质上是能够暂停和恢复执行的函数。通过移除脚本中原始的 Update() 函数并用协程替换它,可以利用协程的强大功能。然后,您可以使用 yield 命令设置协程执行的频率。此代码段显示了如何创建一个自定义的智能更新,该更新每 2 秒调用一次,而不是默认的每帧一次。
      图 13. 使用协程实现更高效的更新

智能内存管理

在寻找优化内存使用的方法时,首先检查 Unity Profiler 会很有帮助。要全面了解您的内存管理情况,可以检查“概述”窗口的“GC Alloc”部分(图 14),然后逐步检查您的帧,直到发现显著的分配。

图 14. 通过连续检查多帧,您可以确定 GC 何时发生并进行调整

检查垃圾回收的调用频率也很有帮助。要查看此信息,请在“CPU 使用率”子分析器中隔离“GarbageCollector”字段(图 15)。

图 15. CPU 使用率中指示 GC 发生的点

当显示回收时,您可以单击图表中的峰值,然后查找 GC.Collect 的调用(图 16)。通过这样做,您可以查看每次回收所花费的时间。

图 16. GC 统计数据

为了避免频繁的分配,使用结构体而不是类是有利的,这样分配会在栈上进行,而不是在堆上。多次向堆分配会导致显著的内存碎片和频繁的垃圾回收。

缓存常用对象和组件

一般来说,您应该分析您的应用程序,找出最常用的 GameObject 和组件,并确保缓存这些值。任何时候看到一个在每个场景中都被获取的对象,都有机会进行缓存并节省不必要的计算。

同样的概念也适用于 GameObject 的实例化。通常,实例化是一个相对较慢的操作,应避免。如果在每个场景中反复创建和销毁相同的对象类型,那么维护一个对象管理器脚本中的对象列表是很有利的。

Unity 建议使用一个中央游戏管理器来维护所有缓存的游戏对象列表。实施此技术后,您可以包含以下代码片段,通过切换状态按钮或其他控制机制,在实时查看CPU 使用率分析器时,比较这两种方法的性能差异。以下是显示使用量差异的代码段(图 14)。

图 17. 使用 STATE 切换对象

使用 Unity 物理系统时的最佳实践

在 Unity 中处理动态对象时,有一些众所周知的优化方法和需要避免的陷阱。无论您是计划手动移动对象还是让 Unity 控制对象的物理,都要为您的对象添加一个 Rigidbody 组件。这会告知 Unity 物理系统该对象是可移动的。当您想手动移动对象时,只需选中 isKinematic 标志(图 18)。您还应该确保该对象在检查器右上角的静态复选框未被选中(图 19)。

图 18. 选中 isKinematic 以控制对象移动

图 19. 未选中静态属性以将动态对象排除在静态集合之外

为了确保您在应用程序中正确处理动态对象,请打开分析器,隔离CPU 分析器物理子部分,高亮显示落在物理时间步(默认每秒 24 更新)的帧,并验证在对象 FixedUpdate() 调用下的概述窗口中没有出现“Static Collider.Move (Expensive delayed cost)”条目(图 20)。缺乏 Static Collider.Move 消息表明该部分的物理效果正在正常工作。

图 20. 当您未正确管理动态对象时,会出现 Static Collider.Move (Expensive delayed cost)

禁用完全透明的对象

对于使用“Fade Out”渲染模式的材质的对象,或者任何会变得完全透明的对象,请务必在对象完全透明后将该对象的 MeshRenderer 组件设置为禁用。这些对象无论 alpha 值如何,始终会被调度到绘制调用中。例如,有时开发人员会使用全屏四边形来绘制伤害指示器或在事件触发时脉冲进出的晕影效果。重要的是要知道引擎本身不会跟踪对象何时完全透明,如果不加以注意,资源将会被浪费。以下截图是在同一场景中拍摄的,唯一的区别是前景中半透明对象的 alpha 值。

图 21. 五个半透明平面及其对应的 GPA 帧捕获。半透明对象可见,占场景的 37.4%,耗时 2,657.5 μs。

图 22. 上述五个平面的材质 alpha 值设置为 0。对应的 GPA 帧捕获显示 GPU 仍在执行绘制命令。这些绘制占场景的 32.1%,耗时 2,316.5 μs。

为确保您没有调度不必要的绘制调用,请尽可能检查潜在透明对象的 alpha 值。对于基于颜色渲染的简单材质,只需使用类似以下代码段的机制。

图 23. 编辑对象透明度时,务必检查其可见性,并在必要时禁用它以节省资源。

继续教程第三部分
适用于 Intel x86 平台的 Unity* 优化指南:第三部分

© . All rights reserved.