本指南概述了典型的游戏开发周期。阅读本指南后,您可能会发现将其用作参考很有帮助。
当您使用 Unity 时,开发周期包括三个阶段
- 计划和设计
- 开发和测试
- 发布和维护
计划和设计
在计划和设计阶段,您确定如何构建游戏。您决定如何解决移动开发的挑战,并确定开发中要使用的工具和流程。
获取所有团队成员的意见
与美术、工程、设计、音频和制作团队合作,识别和记录实施任务。例如
- 美术团队可能会为角色和环境创建资产纹理和网格预算。
- 工程可能会确定内存和性能检查点,以便针对每个平台进行分析。
- 设计可能会计划实现体验的游戏机制。
- 音频专家可能会审查 UI、2D 和 3D 空间声音之间声音连续性的要求。
- 制作可能会传达发布要求,并使团队保持一致和步调一致。
为移动设备设计
针对移动平台的应用程序开发涉及特定考虑因素,例如
- 可变屏幕纵横比
- 功耗
- 热量和处理器降频
- 触摸输入
- 跨平台开发
- 图形 API(Vulkan 或 OpenGL ES)
有关为移动设备设计特有的考虑因素的详细信息,请参阅 Unity 的 Unity 中的 Android 开发 和 Google Play 学院。
开发和测试
在开发和测试阶段,您构建游戏并进行测试和发布前准备。您会在 Google Play 上进行一些有限的 内部测试,以便您准备好满足发布要求。您完善部署策略,并根据 Play Asset Delivery 和 Unity Addressables 系统在 Unity 中组织资产。
以下部分介绍旨在帮助您为 Android 开发的 Unity 工具和技术。
渲染
渲染是将 Unity 场景中的 3D 和 2D 资产绘制到屏幕上的过程。虽然 Unity 引擎处理渲染,但重要的是要考虑 Android 平台的一些因素。
纹理
根据目标设备确定是否需要最大的纹理尺寸。当您分析 内存分配 时,请查看更改目标纹理尺寸的潜在节省。
帧时间
为了防止 Android 设备过热,平均目标帧时间值应低于 21 毫秒。有时,例如在加载或简短的电影体验期间,您的帧时间可能会超过 21 毫秒,但您应该在核心游戏体验中保持在 21 毫秒阈值以下。
在移动平台上,强制 VSync 会在您未达到最小目标帧率时降低帧率。例如,在 60Hz 屏幕更新上,如果您没有达到 60fps,您的游戏将被降低到 30fps;如果您没有达到 30fps,则会降低到 15fps。
许多 Android 设备出厂时都配备了 60Hz 和 120Hz 的显示屏刷新率。权衡在不冒热量降频和电池消耗风险的情况下,针对更短的帧时间(60Hz 更新的目标为 10 毫秒,120Hz 的目标为 5 毫秒)带来的优势。
要在 Unity 中设置游戏中特定的帧率,请使用 Application.targetFrameRate。
Android 帧速率同步库 可帮助您在应用程序呈现下一帧的时间比屏幕刷新率要求的时间更长时平滑地呈现。对于 Unity 2021 及更高版本,启用 Android 帧速率同步会将显示刷新率设置为与目标帧率最匹配的刷新率。这确保游戏不会在不必要的显示更新上浪费电池电量。
要启用该库,在 **项目设置** > **播放器** 下,在 **Android 设置** 下,选中 **优化帧速率同步** 复选框。
Vulkan API
Vulkan 是一种跨平台、高性能的 3D 图形 API,与 OpenGL ES 相比,其开销很低。Unity 可以通过两种不同的方式使用 Vulkan。
自动图形 API
您可以将 Vulkan 与自动图形 API 结合使用,但这会根据您安装的 Unity 版本而产生不同的行为。您可以通过导航到 **项目设置** > **播放器** > **渲染** 来选择此选项。
选择使用哪个 Unity 版本时,请牢记以下注意事项
- Unity 2021.1 及更早版本不支持使用 Vulkan 与自动图形 API 结合使用。Unity 尝试使用 OpenGL ES 3.2。如果设备不支持 OpenGL ES 3.2,则 Unity 会依次回退到 OpenGL ES 3.1、3.0 或 2.0。
- Unity 2021.2 及更高版本首先使用 Vulkan。如果设备不支持 Vulkan,Unity 会回退到 OpenGL ES 3.2、3.1、3.0 或 2.0。
手动图形 API
或者,您可以通过禁用自动图形 API 来手动启用 Vulkan。如果您使用的是 Unity 2021.1 或更早版本,这是使用 Vulkan 的唯一方法。
如果 Vulkan 在此列表中排在 OpenGL ES 的前面,则 Unity 首先尝试使用 Vulkan。如果设备不支持 Vulkan,则 Unity 会使用 OpenGL ES 运行。有关 Android 上 Vulkan 的详细信息,例如如何使用现代图形 API 并优化游戏性能,请参阅 Vulkan 入门。
绘制调用
屏幕上显示的所有内容都与一个或多个绘制调用相关联。在移动平台上,您应该优化和减少发送到图形处理单元 (GPU) 的绘制调用数量。
将绘制调用视为类似于在交通灯前排队的汽车。交通灯变绿后,在交通灯再次变色之前,可以有若干辆汽车通过。当交通灯变黄时,您就达到了理想的目标帧时间(21 毫秒),而当交通灯变红时,您就达到了 33 毫秒的帧时间限制。超过该限制会影响下一帧的渲染,因此产生的帧率低于您的目标 30fps。
有关如何改进游戏绘制调用性能的信息,请参阅 Unity 支持的 批处理 文章。
阴影
阴影投射绘制调用可能是最占用 GPU 资源的,即使对于简单的环境,也会占用大部分 GPU 时间。为了降低阴影投射绘制调用的成本,请尝试使用硬阴影而不是软阴影。如果对于低端设备来说,这仍然过于占用 GPU,请考虑使用点状阴影而不是硬阴影。
纹理
Android 上的 RGB 和 RGBA 纹理推荐使用 ASTC 纹理压缩格式。在 Unity 中,Android 上应该使用的最小纹理压缩选项是 ETC2。您可以在 **Unity 构建设置** 下将 ETC2 作为 ASTC 的备用方案。
在 Unity 文档中,可以找到按平台列出的所有支持格式的完整列表,请参阅 手册:按平台推荐、默认和支持的纹理格式。
用户界面和纵横比
您可以使用 Unity 设备模拟器 工具在 Unity 编辑器中直接预览各种设备屏幕分辨率、方向和纵横比。您可以切换游戏视图和设备模拟器视图。
在 在 Unity 中使用设备模拟器模拟您的游戏! 中可以预览该工具。
您可以在 GitHub 上的 games-samples 存储库中找到 Trivial Kart 源代码。
通过在下拉菜单中选择设备选项,您可以快速验证设备模拟器视图中 UI 画布元素的布局和正确性。
有关 Unity 的更多 UI 优化技巧,请参阅 Unity 的以下教程:优化 Unity UI。
物理
Nvidia PhysX 引擎内置于 Unity。默认设置在移动设备上可能很昂贵,因此请记住以下注意事项。
- 请考虑您的目标帧速率,并相应地设置固定时间步长。默认设置为 0.02 毫秒或 50 赫兹。对于 30 帧每秒的目标,您可以将其增加到 0.03 或更高。
- 请考虑简化网格碰撞器,并最小化层碰撞矩阵,以确定特定层类型游戏对象的交互。
有关 物理设置 和移动游戏优化的信息,请参阅 Unity 的 优化您的移动游戏电子书。
性能分析
应用程序开发人员经常忽视或忽略性能分析,直到应用程序遇到严重故障。最好将专门的性能分析时间安排到您的流程中,并使用以下最佳实践。
- 确定开发过程中的关键时间点,您可以在这些时间点分配性能分析时间,而不是随机分配。
- 保存性能分析快照,以供 Unity 性能分析器 使用。
- 在目标设备上对游戏进行性能分析,以准确了解游戏在当前开发阶段的性能。
- 对游戏的不同部分进行性能分析。
- 分析玩家如何玩游戏。(不要只在游戏处于空闲状态或暂停屏幕时分析游戏。)
- 在游戏运行一段时间后,在持续模式下进行性能分析,以帮助查找移动设备 过热 时可能遇到的节流问题。
您可以单独或组合使用以下性能分析工具。
Unity 性能分析器 Unity 性能分析器是一个完全集成的性能分析工具,可以在 Unity 编辑器中针对您的代码运行,并连接到运行开发模式构建的独立 Android 设备。
Android GPU 检查器 使用 Android GPU 检查器 (AGI),您可以执行帧级调试。AGI 还分析系统服务,包括 GPU、CPU、内存、电池和 GPU 计数器。
有关在 Unity 中分析游戏的详细信息,请观看视频 Unity 性能分析入门,或阅读 Unity 的 Unity 游戏性能分析终极指南。
内存管理
Android 进程共享目标设备上的可用内存。在目标测试设备具有充足的空闲内存资源时,您应该分析内存使用情况。在游戏中的一个一致点执行内存测试,以便您可以适当地比较会话和内存使用趋势。
在使用 C# 编写的脚本中,请谨慎使用字符串、字符串比较以及字符串相关对象的分配(例如游戏设置的 JSON 文件)。这些操作会产生频繁的内存分配,并可能导致碎片化。
请考虑使用 StringBuilder 类进行大量字符串操作,而不是就地串联字符串(例如,"this" + "is" + "a" + "bad" + "idea" 与 StringBuilder.Concat()
函数调用)。
有关字符串的更多信息,请参阅 Unity 文档中的 字符串和文本。
评估 TextAsset 和 JSON 文本资源与首选的 ScriptableObject
类型。ScriptableObjects
可有效处理跨场景数据存储,并允许进行编辑器到播放时间的修改。
有关使用默认 JSON 处理程序的替代方案以进行移动优化,请参阅 Hutch 上的文章 网络游戏中隐藏的优化。
使用 内存建议 API 确定运行时的内存使用情况。该 API 公开了一个红绿灯指示器,用于指示高、正常和低内存使用情况。您可以订阅指示器以获取更新,或直接轮询它以获取当前状态。收到红色信号时,请考虑减少游戏对象池或缓存。在游戏运行期间将此上下文包含在您的游戏遥测中,并在发布后审查性能指标。
要深入了解 Android 设备上的内存组织以及 Unity 如何与其配合使用,请观看 了解 Android 内存使用情况(来自 Google I/O '18)。该视频介绍了各种内存问题,以及低内存杀手何时生效。
垃圾回收
在托管内存环境中,垃圾回收会清理未使用的内存碎片,这些碎片可以被应用程序回收。请遵循 垃圾回收最佳实践,以避免不必要的内存资源分配。
例如,创建游戏对象池,而不是使用按需分配 (GameObject.Instantiate
)。对于大型池,请考虑跨多个帧进行分配,以降低游戏在入门级 Android 设备上无响应的风险。
请考虑以下用于简单协程的代码片段,该协程从 MonoBehaviour 的开头调用。
// Option 1: Bad for memory management - causes allocation each iteration
IEnumerator UpdateEnemyTarget() {
while (enabled) {
yield return new WaitForSeconds(1.0f);
// Some intermittent function check
}
}
// Option 2: Better for memory management - allocation of yield instruction once, reused each iteration
private YieldInstruction waitForSecond = new WaitForSeconds(1.0f);
IEnumerator BetterUpdateEnemyTarget() {
while (enabled) {
yield return waitForSecond;
// Some other intermittent function
}
}
您可以 编辑 MonoBehaviour 模板文件以删除默认的 Start()
和 Update()
存根函数,这样您就不会在开发过程中无意中留下空函数。
有关 MonoBehaviour 事件执行顺序的概述,请参阅 Unity 文档中的 事件函数的执行顺序。要详细了解内存管理,请参阅课程 Unity 中的内存管理。
有关移动游戏性能优化技巧,请参阅 优化您的移动游戏性能:Unity 顶级工程师提供的有关性能分析、内存和代码架构的技巧。
预制件池
CPU 帧时间峰值几乎完全由游戏过程中预制件实例化引起。请考虑在进入游戏之前预热弹药、可生成敌人和视觉效果的对象池,以减少或消除启动 CPU 峰值。您可以在场景加载或介绍序列期间跨多个“初始化帧”分散额外的优化。
您可以在 Unity 资源商店 上找到许多与游戏对象池管理相关的第三方池资源。您也可以创建自己的。请参阅 Unity Learn 上的对象池入门。
资源交付
应用程序首次部署到 Google Play 时,其大小有限制。根据游戏的大小和性质,您可能需要某些或所有游戏资源(角色模型、环境、UI 元素等),以便玩家获得您预期的体验。
您可以使用 Play Asset Delivery (PAD) 服务管理游戏在安装时、快速跟踪或按需需要的资源。Unity 资源包已集成以支持 PAD,您可以使用该工具指定要交付的元素。
可寻址资源
如果您准备并审查了可寻址资源命名系统,则在运行时设置动态资源(例如预制件、纹理和声音文件)不再是复杂的操作。可寻址资源将内容的安排方式与构建和加载内容的方式分离。可寻址资源系统取代了 Resources 文件夹和资源包,简化了对资源的引用方式以及在运行时加载资源的方式。
例如,请参阅 GitHub 上的 使用可寻址资源包的演示项目。有关可寻址资源开发的详细信息,请参阅 Unity 博客上的可寻址资源系统。
使用可寻址资源布局时,将太多或太少的资源捆绑到公共捆绑包中,存在优缺点。要详细了解使用可寻址资源进行内容管理,请参阅 使用可寻址资源简化内容管理。
您可以设置一个独立的演示,并尝试使用访问模式来熟悉可寻址资源系统。您还可以查看开源项目 适用于 Unity 2019.3 及更高版本的 BuildLayout Explorer,并检查可寻址资源生成的 buildlayout.txt
报告。
Chop Chop(一个 Unity 开放项目)的资源使用可寻址资源系统打包,用于所有加载和卸载操作。请参阅 使用可寻址资源打包内容 | 开放项目开发日志,以了解如何配置可寻址资源捆绑包的结构和设置。
在 Chop Chop 项目中,默认加载的唯一场景(初始化场景)被配置为使用 AssetReferences
,而不是项目中资源的直接链接(场景、预制件等)。
您可以在 GitHub 上获得 Unity 开放项目:Chop Chop 的源代码。虽然该项目已不再开发,但 git 存储库和文档仍然可用。
第三方插件
如果您使用第三方插件,例如 Unity Asset Store 中的插件,请确保您检查文件夹并从Resources文件夹中删除不必要的资产。在构建过程中,Unity 会收集Resources文件夹中包含的所有资产,并将它们打包到一个在运行时可访问的单个捆绑包中。这会导致最终包膨胀,而且通常是不必要的。
要快速找到所有资源文件夹,请在项目面板中搜索Resources。然后,您可以选择每个文件夹以识别它包含的内容以及它是否对您的游戏必要。
发布和维护
当您准备发布您的移动游戏时,请确定您要发布给谁、如何进行 alpha 和 beta 测试,以及如何在发布后监控和跟踪性能。
分析有限发布的反馈
您可以向有限的目标受众发布,并进行更大规模的 beta 测试,或激活您的游戏以在所有市场中完全可用。通过有限发布,您可以根据更广泛的实时受众和设备集合调整应用程序性能。
例如,您可以使用 适用于 Unity 的 Android 性能调整器 和 适用于 Unity 的 Google Analytics 来获取有关应用程序性能和玩家趋势的洞察,您的开发团队可以据此调整和推送更新。您还可以使用分析数据来规划类似类型游戏的续集或相关游戏。
alpha 和 beta 测试
在您在 Google Play Console 中设置应用程序配置文件后,您可以准备公共 alpha 和 beta 测试构建,并将它们分发给有限的受众,以便在发布前进行审查。通过向有限的受众发布,您可以解决与更大范围的设备相关的任何最终问题,并收集在全球发布之前可以响应的初始反馈。
您的 Unity 构建通过 Android 应用程序捆绑包分发。有关信息,请参阅来自 Unity 的 手册:向 Google Play 发布,其中还描述了从 APK 文件到 AAB 格式的更改。
监控和跟踪
在游戏的运营和分发阶段,您可以使用 Android 关键指标 来帮助找出您可能在开发和测试期间无法访问的设备上的性能问题。有关详细信息,请观看 Reach 和设备以及 Android 关键指标中的游戏新功能。
通常,规模较大的开发团队拥有独特且定制的游戏遥测管道,这些管道提供与设备性能相关的指标。请务必利用 Android 性能调整器 (APT) 和相应的 Unity 插件来调整与帧速率、图形保真度、加载时间和加载放弃相关的指标。按照 将 Android 性能调整器集成到您的 Unity 游戏中 中的逐步指南进行操作。
您的游戏的生命周期不会在您上线后停止。监控、维护和响应性能和反馈对于用户满意度、正面评价以及在所有市场中最终采用您的游戏至关重要。