使用 Unity Tilemap 优化 2D 游戏的性能
这些技巧最适合那些曾经使用过 Unity 2D 工具集的用户。对于使用 Unity 开发商业 2D 游戏的专业创作者来说,另一个宝贵的资源是我们的电子书、2D 游戏艺术、灯光和动画。
如果您是使用 Unity 开发 2D 游戏的新手,请 从新用户 2D 指南开始。
以下是一些需要考虑的一般性能技巧:
- 从一开始就考虑你的资产(数据)的性能。如果这些元素性能不佳,那么您以后几乎无法优化代码。
- 在最低端可用目标设备上进行配置。在整个项目开发过程中使用 Unity Profiler 以及特定于平台的分析工具,例如适用于 iOS 设备的 Xcode。
- 不要使用超过最低端目标设备上可用 RAM 的三分之一。这可以确保您的内容能够在各种移动设备上良好运行(廉价的 Android 手机在移动市场上仍然最受欢迎)。
有关更多 2D 优化技巧,请参阅以下资源:
Tilemap 组件允许您使用网格覆盖上的图块有效地创建 2D 级别。它由许多要素组成,包括:
您可以使用 Sprites 和 GameObjects 的组合来创建 2D 级别,并控制诸如 Sorting Layers、Tilemap Colliders 和 Animated Tiles 等属性。您还可以绘制 正方形、 六边形和 等距精灵。
使用 Tilemap 绘制您的关卡,以便当应用于 Tilemap 游戏对象时,Tilemap Collider 2D 组件将自动在 Tile 周围生成一个 Collider(基于 Tile 的 Collider Type 设置)。
让我们看看与使用 Sprites 构建的场景相比,使用 Tilemap 可以获得哪些性能提升。
使用 Tilemap 可减少加载时间以及内存和 CPU 使用率。
如果您以前开发过 2D 游戏和应用程序,那么您就会知道,您的游戏中可能会有大量的 Sprite,它们全部都是单独的 GameObject。每个 Sprite 游戏对象上都有组件,包括一个 Transform 和一个 Renderer,它们都占用内存。其他组件(例如对撞机)会产生 CPU 开销。
相比之下,Tilemap 使用一个渲染器来呈现整个地图及其所有图块。与跨内存的多个数据结构相比,由于它只处理自己的数据结构,因此可以减少开销。
游戏对象越少,层次越清晰,这意味着您不需要滚动复杂的列表来查找所需内容。
Unity Tilemap 减少了场景尺寸。拥有更少的游戏对象和组件意味着运行时从磁盘加载、反序列化和保存在内存中的对象更少。
在 Unity 中加载场景分为两部分:首先,从磁盘读取数据。此过程通常会占用游戏中最多时间,尤其是在 Android 设备上。然后数据被反序列化。反序列化是将数据从一种格式转换为另一种格式的过程。本质上,它从已保存的状态恢复数据和对象。Unity 在内部进行序列化,以便每当它在编辑器中和运行时加载场景文件时,它都会获取这些保存的文件并将其转换为 Unity 对象。
在上图中,您可以看到两个序列化场景文件的比较,一个使用 Tilemaps,另一个使用 Sprites 重新创建。感谢 Pixel Reign 为他们的游戏 Robbie Swifthand提供这个场景。
右侧是序列化 Tilemap 的一部分,由四个图块组成。所有图块的规则(包括使用的图块类型)均在 Tilemap 的顶部设置。每个后续的瓷砖都说明了其属性,例如所使用的瓷砖及其位置。
左边是一个 Sprite,带有 Transform 和 Sprite Renderer 组件。
通过这个比较可以清楚的看出Sprite序列化需要做多少工作。具体来说,使用 Sprites 的场景文件中有 370,000 行,而使用 Tilemaps 的场景文件中有 30,000 行。更小的项目和仓库规模可带来更快的迭代时间和更顺畅的工作流程。
如果您想将自己的场景视为文本文件,请进入 编辑器设置,打开 资产序列化模式,单击 强制文本,然后在 文本编辑器中打开 .unity 场景文件 。
您可以将 Tilemap Collider 2D 与 Composite Collider 结合起来。这不仅会减少碰撞器和精灵的数量,还可以提高您的生产效率,因为每次进行更改时无需重建复杂的碰撞形状。复合对撞机负责处理这个问题。
如前所述,每个 Sprite 都有一个 Sprite Renderer 组件,渲染器越多就需要 CPU 做更多工作,包括剔除准备和渲染清理的时间。通过使用 Tilemaps,您将拥有更少的渲染器组件,从而节省 CPU 的一些工作。
场景中有多台摄像机意味着有更多的渲染器。这会增加淘汰成本。
在“摄像机”视图中,每个渲染器、每个摄像机都会产生剔除成本。每个摄像机都必须对场景中的每个渲染器组件执行剔除检查,因此如果您的游戏设置了多摄像机,使用 Tilemaps 将帮助您降低成本。
批处理就是收集所有可以绘制的几何图形,而无需进行另一个 SetPass 调用。Tilemap Renderer 根据 Sprite 的位置对其几何形状进行批处理。结果是,与 Sprite Renderer 发送更多网格但较少几何图形相比,Tilemap Renderer 向渲染管道发送更少网格但更多几何图形。如下节中的表格所示,基于 Tilemap 的场景的批次明显较少。
您可以通过查看游戏视图中的统计面板来检查批处理。您还可以使用 Frame Debugger 来确定项目未分批的原因。
为了达到 60 fps,每帧最多需要 16 毫秒来渲染。当在旧款 iPhone 7 上分析示例场景时,基于 Sprite 的版本每帧为 244 毫秒,而 Tilemap 版本每帧为 13 毫秒。
最后,基于 Sprite 的场景的 RAM 使用率为 1.1 GB,这对于低端 Android 手机来说太多了。基于 Tilemap 的场景仅使用 21 MB 的 RAM,使其适合在更广泛的移动设备上运行。
上面的比较显示了两个场景之间明显的性能差异。
Sprite Atlas 是一种编辑器工具,可让您将 Sprite 打包在纹理中,以优化内存使用和绘制调用。创建一个 Sprite Atlas Asset,其中包含 Tilemap 中使用的所有精灵,以便 Tilemap Renderer 可以在一次绘制调用中对它们进行批处理(只要所有精灵都适合单个纹理)。