作者:Jacques Lebrun & Noel Lukasewich
文章来源:https://www.unrealengine.com/zh-CN/tech-blog/taking-the-leap-on-nightingale-how-inflexion-games-upgraded-from-ue4-to-ue5-mid-development?tags=tech-blog
文章类型:原文转载
我们是Inflexion的两名开发者,Jacques Lebrun和Noel Lukasewich。我们和其他几位开发者曾致力于将我们即将推出的《夜莺传说》项目升级到虚幻引擎5中。
去年,UE5首次发布,我们团队迫不及待地想要利用它所带来的新功能和新机遇。然而,最初,想要将项目从虚幻引擎4迁移到虚幻引擎5中似乎是一项艰巨的挑战。在这篇文章中,我们将深入探讨在生产环境中升级项目所要做的工作,并提供一些或许可以帮助你成功迈出这一步的建议。
关于源代码控制工具的说明:在我们的案例中,我们通过Github获取引擎更新,然后通过Perforce维护和控制我们自己的源代码,然而,即使你使用的是其他配置方式,仍可从本文中获益。
在探讨升级流程之前,有必要谈谈我们的动机,以及我们为什么愿意付出额外的努力,在UE5发布初期就开始使用它。
最吸引我们的激励因素是,Lumen和Nanite能够相辅相成,使创造更强大的视觉效果成为可能。起初,鉴于所有资产都是在未考虑Nanite的情况下创建的,我们认为将项目迁移到Nanite中是不可能的(剧透:最终我们还是转向了Nanite,稍后会详细介绍),然而,单单是Lumen所展现出的改进,就足以吸引我们将升级纳入考虑范围。另外,我们预见到,在开放世界系统、资产管理以及整体开发效率方面,工作流程即将迎来大量改进。
最后,随着我们的项目进入“抢先体验”阶段和“游戏即服务”生命周期,我们知道,我们的玩家社区迟早会驱使我们改进技术和视效,这只是时间问题。
确定动机之后,我们开始考虑升级的总体成本。Epic估算,相较于完成UE4的小版本升级,从UE4升级到UE5所需的成本大约是前者的四倍。我们曾经花费一两个月时间升级小版本,因此,我们预计这次大概可能需要六个月。结果,这个预估非常准确。
此外,我们发现,确定阻碍的最简单方式就是直接开始,并检查出现的问题。在我们的案例中,主要问题来自从物理引擎向Chaos物理系统的迁移,但考虑到我们的游戏并没有太多自定义物理功能,因此,我们认为这种风险是可控的。
对于蓝图项目,升级引擎应该非常简单:没有需要更新的代码,只需在新的引擎版本中加载项目,看看出现了哪些资产错误,然后修复引擎抛出的问题。
升级代码项目涉及更多事项,我们将在此处探讨。关键在于对引擎的定制程度。如果你从未修改引擎,升级将同样非常简单;然而,如果你大幅修改了引擎,那么,你需要付出的努力就瞬间增多了。我们介于两者之间,采用以下做法管理升级流程。
标记并跟踪你对引擎的更改将起到帮助作用,这将简化合并代码冲突的过程。对于《夜莺传说》,我们遵循以下流程:
// NTGL_BEGIN - NTGL-1234 - [改进] 修复未初始化的变量
// int IntVar;
int IntVar = 0;
// NTGL_END
更新引擎在一开始可能很简单,只需从Epic的Github获取更新,替换Engine文件夹下的所有内容,然后通过P4V协调离线工作;然而,随着你不断对引擎代码做出更改,这种方式将迅速变得难以管理。
我们利用Perforce的流仓库建立了以下分支:
仓库/流 | 描述 |
---|---|
//ue4/release-4.27 | 未经修改的UE4/UE5版本镜像 |
//ue5/release-5.0 | 未经修改的UE4/UE5版本镜像 |
//ntgl/dev | 主开发流,团队的大部分成员将在这里工作 |
//ntgl/integrate | 开发流的子流,你将在这里合并引擎更新:在所有问题都得到解决之前,该流预计会处于损坏状态 |
开始升级至UE5之前,你需要从UE4的最终版本(//ue4/release-4.27)完成向整合流的合并,以建立修订历史。如果你还未使用4.27版本,可能会考虑一次跨越多个版本进行升级。但根据我们的经验,采用渐进方式,每次只升级一个版本通常是比较简单易行的。
接下来,你可以按照以下方式,建立release-5.0分支:
更新和合并步骤现在变为:
1. 将开发流中的所有更改合并到整合流中
2. 将所需的虚幻版本镜像同步到单独的Perforce仓库中(例如//ue5/release-5.x)
3. 从//ue5/release-5.x合并/整合到//ntgl/integrate
4. 解决合并冲突并提交
这些步骤全部都可以手动完成,但如果投入一些精力,通过编写脚本实现自动化,你将享受到极大的益处。
在合并更新后,你可以将引擎升级任务分解为以下几个不连续的步骤:
5. 修复与代码项目生成相关的警告和错误
6. 修复编译和链接错误
7. 修复编辑器和烘焙错误
8. 修复自动化测试失败错误
9. 修复游戏漏洞
在自动化方面的投入有助于大幅简化升级流程。在理想状况下,你应该拥有一套可重复执行的构建流程,可针对你的整合流运行,并在合并到开发流之前验证一切是否正常。还有一些方面,也能够起到帮助作用:
在升级过程中,我们遵循以下各种简化流程的技巧。
p4 -F %localPath% resolve -n | p4 -x - reopen -c [new changelist #]
修复编译和链接错误时,使用-DisableUnity进行编译。这将关闭虚幻编译工具中的编译优化(将多个.cpp文件合并成一个)。编译将花费更长的时间,但是跟踪编译问题会变得更容易,这也将让你捕捉到include语句缺失的问题。
如果你通过github获取虚幻引擎,就需要决定如何填充从GitDependencies.exe获取的文件。你可以让开发人员单独更新这些文件,或者和我们一样,将这些文件合并到镜像自动化脚本中,然后将这些文件提交到我们自己的Perforce镜像中。
密切关注虚幻引擎的废弃警告,因为这些警告通常会为你指明升级项目的正确方向。将编译警告数量降至0,这样可以让你更轻松地跟踪并处理这些废弃功能。
在整合流中包含所有资产,这样一来,你将能够根据需要升级单个资产。虽然我们不需要经常做这样的工作,但如果时常在主开发流修改这些资产,管理起来将非常繁琐。对此,我们可以提供一些有帮助的建议:
(1)如果你能仔细挑选一些最小的引擎更改纳入开发流,并在开发流中更新资产,将消除发生冲突的可能性。
(2)如果你能够使用命令行升级资产,则可以创建一条在每次合并后运行的命令行,以确保所有相关资产都是最新的。在许多情况下,你只需在最新版本的编辑器中重新保存资产。
即使引擎版本尚未进入抢先体验状态,Epic仍允许你访问该版本分支。这允许你提前开始合并即将发布的版本,并缩小一次合并的代码量。同样,日常从开发分支进行合并,能让你在遇到存在困难的合并时立即中止,以便与相关开发人员合作解决问题。
如果你依赖来自商城或其他供应商的第三方插件,在插件更新之前,最好等待。我们经常会希望在这些插件得到更新之前就进行升级,这意味着,需要花费额外的精力来更新插件。然而,如果你再等一段时间,就可以“免费”获得这些插件。
引擎每次升级都会带来一些非常有用的功能。尽管立即开始使用新功能很有吸引力,但我们始终会首先推送对游戏或开发人员工作流程几乎不产生实质更改的引擎更新。仅当我们在开发流中确定这次升级具有稳定性后,我们才会开始尝试新功能。
升级到Lumen和Nanite带来了令人兴奋的可能性。谁不想获得更精确的反射光照,谁不想大幅增加游戏的多边形预算?
虽然开启Lumen和Nanite很容易,但《夜莺传说》的准备工作还是花了一些时间,因为游戏最初是为UE4优化的。《夜莺传说》在管线的所有组件中都严格地遵守了PBR规则,因此在集成Lumen后,它迅速地让我们的游戏变得更闪耀了;另一方面,将网格体转换到Nanite之后,我们能够实现额外的优化。
将项目转换到Nanite花了更长时间,因为我们也希望利用虚拟阴影贴图。虚幻引擎5支持Nanite和非Nanite资产互通,得益于此,我们可以逐步转换,这让我们在过渡期间仍能确保游玩体验完整。也就是说,随着越来越多的资产转向使用Nanite,你将看到虚拟阴影贴图提升了性能,因此,这个转换过程将让你了解游戏将有怎样的性能表现,从而起到一定的激励作用。
单个资产的转换过程往往可以归为以下几类:
另一个对我们工作流程帮助极大的方面是引入关卡实例和打包的关卡Actor。在UE4中,我们一直在努力实现各种预制组件,但打包的关卡Actor为我们创造了新的可能性,使我们能够在《夜莺传说》中以程序化方式组装环境。
随着版本从5.0更新到5.2,我们看到引擎的许多功能都得到了改进,例如体积云渲染,以及Lumen的植被渲染。最后,Nanite、Lumen和虚拟阴影贴图的组合带来了相当震撼的视觉效果。
在经历了UE5的改造后,我们对《夜莺传说》的外观感到非常满意。如果没有Lumen和Nanite,我们不可能实现如此高的保真度,我们期待通过《夜莺传说》和虚幻引擎5的未来更新将游戏外观推向新高度。