独自开发人员分享关闭β测试的故事。性能修复基本上都是Unity风格的教科书 (OSA循环滚动 + 缓存TMP设置) 但是最大的解锁是如何解决面板为什么在第一时间很贵。

设置

我有一个"区域物种"面板,设计为快速浏览:打开几秒钟,查看统计数据,关闭。在beta期间,测试分析表明有两个意外行为:

1.大多数玩家将面板 打开整个会话
2 大多数玩家配置为 显示每页的最大数量(我已经暴露在平板电脑和更大的屏幕上,假设人们会降低他们的设置)。

面板已经在unity的 perf 指南下有自己的子画布 - 那个部分是可以接受的。但 \~60 个物品(后期)× 始终渲染 = \~28 ms/帧在最坏的情况下,结果破坏了我的帧预算。

\> 为什么玩家会在最大项数上?

他们试图找到一个合适的植物而不需要滚动。我使用的默认排序是有问题(字母顺序一些)这不是找到目录的高效方式,玩家只好最大化项数并进行视觉模式匹配。

最大的胜利是UX修复,而不是性能修复。

重新排序(根据环境适合性排列,给出玩家的当前生物栖息地)。玩家立即停止最大化项数:他们不再需要,在面板顶部,有相关植物。

这就减少了大多数用户的呈现的物品数量的一倍。免费的性能收益来自一行默认排序的改变。

但面板仍始终打开。两种Unity解决方案如下:

一、OSA(优化滚动视图适配器)

vanilla Unity ScrollRect实例化了 每个项目。即使有更少的行现在显示因为排序修复,以及屏幕大小 \ ~ 8-12 在滚动时,屏幕将不再显示的项目(~2 - 3 行×4 个项 / 行)仍在控件树中 - 跳闹,支付了没有打的layout发牢。下降使用OSA。只有在滚动时才实例化可见的项目(~8 - 12 项,视窗大小依赖于,~2 - 3 行 × 4 项/行)。重新利用它们。和RecyclerView(Android)或UITableView(iOS)的模式相同。转换了我的行预置体到一个OSA物品的成本大约1h。

二、缓存TMP更新(滑稽一条)

每行都有实时数字。我每帧都分配给TMP、甚至当显示的值与之前的值相同。

' TMP setText ''不是免费的 - 它们引发的是mesh重新生成。~30行× 30 FPS× ~ 3 个字段= ~ 2,700个无谓的重新生成每秒,大部分都是设置相同的字符串。

切换为缓存包装器来计算显示的显示字符串(例如 "1000 m"变为 "1.0 km"),并在更新之前与当前显示的字符串进行比较。

关键的是比较格式化的字符串,而不是原始值。比较原始值减少了减少了3倍的重绘。比较格式化的显示字符串削减了 50x 多在现实中的会话中,因为+10 m² / 帧的增长率,所显示的值(‘0.0 hm² ’)只改变每100帧一次。

结果: 从 ~ 28 ms/帧到 ~ 0.18 ms/帧。

教训:性能问题是起因的UX决定(糟糕的默认排序)。玩家通过最大化项数来应对,而始终打开的面板才暴露了性能成本。UX修复直接解决了这半数的症状 - Unity修复进一步阻止玩意们仍然打开面板。

如果你有一个面板 "始终打开时很贵",在.optimize渲染之前先检查你的用户是怎么做的。最便宜的修复可能就是他们在使用的设计决定。