Optimizing Unity UI(六):Other UI Optimization Techniques and Tips

版本检查: 2017.3-难度: 高级

有时候,没有干净的方法来优化UI。这一节包含了一些可能有助于提高UI性能的建议,但有些建议在结构上是“不干净的”,可能很难维护,或者可能会产生不良的副作用。其他方法可能是解决UI中的行为的方法,目的是简化初始开发,但也使得创建性能问题相对简单。

RectTransform-based Layouts

布局组件的成本相对较高,因为每次标记为脏元素时,它们都必须重新计算子元素的大小和位置。(有关详细信息,请参阅基础部分的图形重建部分。)如果给定布局中的元素数量相对较少且固定,且布局具有相对简单的结构,则可以使用基于RectTransform的布局替换布局。

通过分配RectTransform的锚点,可以使RectTransform的位置和大小根据其父节点进行缩放。例如,可以使用两个RectTransform实现简单的两列布局:

  • The left column’s anchors should be X: (0, 0.5) and Y: (0, 1)
  • The right column’s anchors should be X: (0.5, 1) and Y: (0, 1)

Transform系统本身将在本机代码中驱动RectTransform的大小和位置的计算。这通常比依靠布局系统更有性能。也可以写设置基于RectTransform的布局的单行为。然而,这是一项相对复杂的任务,超出了本指南的范围。

Disabling Canvases

在显示或隐藏UI的离散部分时,通常会在UI的根处启用或禁用GameObject。这确保禁用UI中的任何组件都不会接收输入或统一回调。

但是,这也会使画布放弃其VBO数据。重新启用画布将需要画布(和任何子画布)来运行重建和重新批处理进程。如果经常发生这种情况,则CPU使用率的增加会导致应用程序的帧速率增加。

一种可能的、但有黑客的解决方法是将要显示/隐藏的UI放置到自己的Canvas或子画布上,然后仅启用/禁用此对象上的Canvas组件。

这将导致UI的网格不被绘制,但是它们将保留在内存中,并且它们的原始批处理将被保留。此外,在UI的层次结构中不会调用OnEnable或OnDisable回调。

然而,注意,这将不会禁用隐藏UI内的任何单行为,因此这些单行为仍将接收Unity生命周期回调,例如Update。

为避免此问题,将以这种方式禁用的UI上的MonoBehaviors不应直接实现Unity的生命周期回调,而是应该从UI根GameObject上的“Callback Manager”MonoBehavior接收回调。无论何时显示/隐藏UI,都可以通知此“Callback Manager”,并确保根据需要传播或不传播生命周期事件。对此“Callback Manager”模式的进一步解释超出了本指南的范围。

Assigning Event Cameras

如果在World Space或Screen Space-Camera中使用Unity的内置输入管理器旁边的画布设置,则务必分别设置事件摄影机或渲染摄影机属性。从脚本中,这始终作为WorldCamera属性进行曝光。

如果未设置此属性,则UnityUI将通过查找附加到带有主相机标记的GameObjects的相机组件来搜索主摄像机。这一查找将发生至少一次,每个世界空间或相机空间Canvases。由于GameObject.FindWithTag速度慢,强烈建议所有的World Space和Camera Space Canvases都在设计时或初始化时分配其相机属性。

此问题不会发生在重叠画布上。

UI Source Code Customization

UI系统被设计为支持大量用例。这种灵活性是很好的,但它也意味着,如果不打破其他特性,一些优化是不容易完成的。如果您最终可以通过更改C#UI源代码获得一些CPU周期,则可以重新编译UI DLL,并覆盖Unity附带的CPU周期。此过程记录在Bitbucket repository 存储库中的自述文件中。确保获得与您的Unity版本相对应的源代码。

不过,这只能作为最后的手段,因为有一些重要的缺点。首先,您必须找到一种方法将这个新的DLL分发给您的开发人员并构建机器。然后,每次升级Unity时,都必须将更改与新的UI源代码合并。确保在朝着这个方向前进之前,不能仅仅扩展现有的类或编写自己的组件版本。

猜你喜欢

转载自blog.csdn.net/Momo_Da/article/details/93623660
今日推荐