我们与Unity已有很长时间的合作,不禁邀请他们的团队参加9月的Pixonic DevGAMM讲座。 现场工程师Valentin Simonov讲述了如何在考虑新技术优势的情况下规划游戏的架构。 Unity多年来一直致力于这些工作,以实现以前无法达到的性能水平。 您可以收听YouTube上的演示文稿,并在剪辑的正下方阅读带有幻灯片的笔录。
如果我说您可以将游戏的生产力提高10倍该怎么办? 实际上,这并非完全正确,但每个笑话中都有一些真理。 我想谈谈我们现在正在做什么,Unity的未来将是什么以及您现在可以使用什么。
Unity制作完全不同的游戏。 这里有一些我自己玩的例子。 他们使用不同的功能,并且需要不同的性能和不同的开发方法。

我们正在开发一个默认情况下称为“性能”的项目。 这些是一些特殊功能,如果使用得当,将可以显着提高性能。 在某些任务中,我们测量了x10甚至x11。 特别是在模拟大量相互交互的对象的问题中。
但是,当我们谈论默认情况下的性能时,意味着您将不得不改变开发方法,极大地改变游戏架构的方法。 而且,实际上,并非每个人都需要此。
一个普遍的问题:“您在ECS中正在做什么? 您删除所有GameObject,删除所有Transform,层次结构和组件吗?” 不,我们都离开。 您可以使用与现在完全相同的Unity进行工作,但是如果要获得更高的性能,则需要了解我想简要谈谈的技术。
我想提到另一种称为脚本可渲染管道(SRP)的技术-它使您可以更有效地为游戏编写渲染管道。 您可能会看到我们在Unite上展示的演示。 在PC上实时模拟大量单位,大约6万个单位(达到10万个并开始放慢一点):
我要讨论的新功能包括:实体组件系统(ECS),C#作业系统,我们的新Burst超级编译器和可脚本化渲染管道(SRP)。

我再说一遍:由您选择是否要继续与我们合作,学习新技术,还是可以开发能赚钱且简单的游戏。
为了了解我们要解决的问题,了解2018年铁的状况非常重要。

请注意,CPU内核的性能和数量是如何增长的。 从某一方面来看,单线程性能甚至下降了。 也就是说,我们现在有很多核心,但是它们的生产力并没有那么快地增长。 因此,我们想利用所有核心的力量。

我的手机有8个核心:4个强项和4个弱项。 一部现代手机可以像一部现代计算机一样快地工作(但由于过热不会很快)。 您还需要了解,不仅要使用所有内核来提高性能,而且还要优化单核性能。
最后一幅图,我们始终以它为例来说明过程性能如何提高以及内存访问速度没有增加太多:

可以看出,现在对内存的访问非常慢。 处理器制造商为解决这种差异做了很多工作-添加缓存,CPU进行推测性计算,试图预测下一步将执行哪些代码。 而且,如果您在制作游戏(或为您制造引擎)时没有考虑它,那么我们将无法充分利用现代处理器。
你们中的许多人可能会花费数小时来查看Unity中的相似图像:

在这里,您可以看到存在多线程,但是其余的内核和线程通常并不忙。 正在进行一些操作,但是我想完全使用它们。
现在我们有了渲染,这是一个黑匣子。 您可以选择:“转发”或“延迟”,以及材质,着色器,命令缓冲区等的各种设置。 您可以制作出精美的图片,但是许多算法都很难实现。

我们都知道Unity中的架构:组件,GameObjects,Transforms的层次结构,所有代码,MonoBehaviour中的所有数据以及每个组件处理其数据。

但是目前的状态存在问题。 迟早您会遇到这种情况,并了解您需要和不需要这样做。 对象本身的层次结构具有一定的开销,并且某些实体完全不必是GameObjects。 而且,如果您有大量的组件并从中进行更新,那么一切都会变慢。 我曾经写过
这篇文章 ,如果您想知道如何不做的话,
这篇文章仍然很重要。

对于处理器而言,最重要的是所有组件,所有数据都分散在内存中,这中断了对处理器缓存的使用。
现在,我想快速浏览一下新功能。

我不会过多地关注ECS是什么以及它如何工作。 关键是我们拥有实体,这只是游戏中某些实体的ID-它们以组件的形式存储数据,即 仅数据,无代码。 然后系统使用某些组件处理实体,并以某种方式更改此数据。
我们为什么要做我们的ECS,它会比竞争对手更好? 有几点。 首先,不是很正式,但是我们认为我们现在就做引擎。 显然,我们不想摆脱Unity的当前组件GameObjects,将所有东西都扔掉并安装ECS。 但是我们希望朝着更好的引擎发展。

我们指望高性能。 不久前,迈克·阿克顿(Mike Acton)加入了我们(如果您从事C ++开发,您会知道他是面向数据编程的传福音者之一)。 我们希望使整个系统尽可能快地工作-比C ++更快。
我们还考虑如何将不同的内容本地集成到ECS中。 不久前,我们宣布我们正在建立一个新的网络,它也是基于ECS的-可以在ECS上制作多人游戏,并在客户端和服务器之间共享代码。
在Unity中使用调试工具。 即 尽管ECS确实与游戏对象和组件分开存在,但这非常不方便。 我们想简化事情。
现在有一个DebugView,看起来像这样:

在这里,您可以看到拥有哪种类型的实体,要使用什么系统,要花费多少时间,要与哪些系统一起使用哪些组件以及对于您可以在检查器中看到的每个组件,每个实体在组件中拥有哪些数据(我注意到,API经常会更改,并且许多教程可能已经过时了。
另外,如果您听说过我们的新开发的Unity for Small Things(这是一个非常小的运行时,它允许您为即时通讯程序制作游戏),那么一切也都建立在ECS上。
最近,发展和向ECS过渡的热潮是一项非常受欢迎的技术,每个人都需要了解它。
我们有一个面向程序员的会议,所以没有代码幻灯片很难做。 那里有很多代码,因此很难抽出一些可理解的代码来使事情变得清晰。

实际上,我从与C#Job System一起使用的示例中选取了一个系统(稍后将对此进行详细介绍),并且我们在减少代码量,添加语法shugar方面做了很多工作。
有一个与RotationData组件一起使用的系统,它还需要GameObject转换,这由特殊的TransformAccessArray表示。 我们创建作业,运行该作业,在某处进行更新的系统的每次更新都可以分为几组,并在不同的线程上执行。
如何在项目中使用? 就像在其他ECS实施中一样,您需要了解必须以完全不同的方式进行思考(与GameObjects和Transforms不同)。 并习惯这个想法。 显然,您需要从项目的一开始就开始,因为我经常会遇到诸如“我们制作了游戏并想切换到ECS-如何?”之类的问题。 在完成的游戏中,这很难做到。

由于ECS单独生活在一个狭小的世界中,因此我们需要通过与Unity的互动进行思考。 我们提供了一些与GameObjects和Transforms进行交互的机会,但是物理,渲染等在这里变得越来越复杂。 尽管您需要忍受一个事实,即许多熟悉的界面将不可用,但我们也在为此进行努力。
立即需要考虑以下事实:您将在作业系统中编写系统,这效率更高。

关于工作系统的几句话。 我们想以一种非常简单的方式来编写多线程代码。 同时,用C#编写代码,为您检查所有内容,不要给自己机会犯错误或显示错误原因,原因和方式。 我们限制了您可以在Jobs中使用的语言功能,并将其称为C#高性能C#。 您的Job代码中没有引用,没有行,所有数据都需要复制-您不能使用大量的语言功能,这使得在腿上拍摄多线程更加困难。
我们还展示了非常快速的集合以及与ECS的集成。 这种ECS和作业系统结构允许非常快速的代码执行。
同时,我们不仅为您提供使用这些技术的机会-我们自己与这些系统一起工作并创建新的API,以便可以在Jobs中使用它们。

我们制作了用于物理的Async Raycasts,您可以说“我想要600个rakecast,请有一天对我进行。” 我们正在努力确保使用这些技术可以扩展当前系统,例如通过Playbles API扩展动画。 我们正在考虑在Unity中创建不会在C ++中关闭且其代码将在C#中并可供您使用的新系统。

如果您使用Job的代码,这非常简单。 Job是一种结构,其中有一个Execute方法,我们通过运行此Job来做一些工作。 因此,我们的内部调度程序将有一天了解在哪里运行它更好,并将解决所有依赖项。 在这里,我们得到一个JobHandle,可以将其用作其他一些Jobs的依赖项。
如何在项目中使用? 如果您从一开始就使用Jobs,那是很好的选择,但这不是必需的。 如果您拥有某种性能关键型系统,例如仿真,寻路,联网或其他功能,则可以找出如何使用此工具对其进行优化的方法。

但是为此,您需要采取一些大步骤,了解如何正确存储数据。 实际上,ECS允许我们正确存储数据,因为我们将数据与代码分开,并且ECS的实现将组件数据线性存储在内存中,并且通过某些系统运行这些组件,您可以使用所有处理器功能,所有内容都存储在缓存中,等 我们尝试非常快地做到这一点。
然后,您将这项工作分解为并行任务,编写作业代码并运行它。 并且(可能)一切都对您有效。 当然,您需要根据核心数量等进行测试,最重要的是,在目标平台上进行测试。 但是,正如我所说,使用Job System和ECS也会极大地影响您计划游戏架构的方式。
然后,一切都变得简单了。 Burst Compiler是我们的独特技术,它是将此C#(高性能C#)子网转换为当前平台机器代码的特殊编译器,您会将其发布到项目中。

伙计们做了一些魔术,除了他们理解之外,没人可能知道,但是这可以将作业代码加快10倍,这真是太酷了。 最酷的是,它不需要您采取任何操作-如果您有作业代码,只需添加[BurstCompile]属性,Burst编译您的代码,即可获得“免费”的性能。 这是我们的新技术,您可以立即尝试。

最后,我要简要提到的是脚本化渲染管道(SRP),我们已经进行了很长时间的研究,它旨在为您提供为特定游戏编写非常自定义的渲染的机会。

Render Pipeline是执行剔除(将绘制对象),渲染和后处理的某种算法。 现在我们有一个黑匣子,可以转发或延迟-它们已经很好,我们可以在手机,PC,控制台上获得非常酷的图形。 但是它们有很多限制,因为它们无法扩展。 使用此新功能SRP,您可以编写管道,也可以从中删除内容,添加内容或执行所需的任何操作。

我们目前正在研究两个管道示例。 一个LWRP(针对我们的手机和薄弱的设备)和HDRP(针对我们的PC,控制台),以及业内非常有名的人士在工作。 在此之前,他们制作了AAA游戏。 当然,您看到了我们的演示版《死者之书》。
在这里,我们使用HDRP展示了这项技术的全部功能。
要使用此功能,您还需要采取大量英勇的步骤,因为对于新的Pipeline,几乎没有任何东西与我们现在拥有的兼容。 即 如果您使用Legacy进行升级,则我们提供了一个实用程序,可以为您升级大多数材质,但是您将需要重写着色器,即 纹理很可能看起来会有所不同。

如果您可以从头开始并尝试使用管道,那就太酷了。 如果您想在管道上做某事,请与我们联系。
再次,了解您的需求,因为现在您有更多的机会去做某事,但是您将需要可以做某事的人,或者您将需要学习如何做。

我认为这很酷,因为那些使用我们这些新技术的人会在市场上有更多的需求。 仅此而已,我希望有人能够研究这些技术,制作出精美,酷炫的游戏。
听众的提问
-我什么时候可以获得ECS并进行开发?-您可以使用ECS,但问题是,按照目前的形式,它更适合于关注绩效的人员,即 某种AAA项目。 Unity的任务是让所有人都能使用默认性能。 因此,我们需要一个特定的系统,即ECS的附加组件,它使我们可以像现在使用MonoBehavior一样轻松地使用ECS。 尽管没有此类附加组件,但我认为ECS不会以完整版本发布。 事实证明,我们做了一项功能,可以让1%的用户使用。 这不是Unity任务。 我知道已经在生产中使用ECS的人,请记住,此功能仍在深入开发中,现在我们正在解决如何制作最方便的界面的问题。 接下来的任务(同样很困难)是如何使某种API驻留在此ECS之上,并使您能够像MonoBehaviour一样轻松地使用它。 即 对于“何时准确”这个问题没有答案。
-ECS和其他项目的重点是制作一些基本的GameObject并制作15万个其克隆并进行管理。 但是,如果我的对象很少,但它们具有不同的实体怎么办?-从原则上讲,您什么也不能做,该技术并不强制您使用它。 如果使用这些技术可以提高性能,则应该使用它们。 如果这与您无关,那么您将继续按原样使用Unity。 因此,请不要惊慌。
-我们在Unity上有一个客户端,在.NET上有一个服务器,我们在Unity上尝试过一个服务器,没有任何好处。 但是同时,我也想使用服务器上Unity中的技术。
-我们正在努力解决这一问题,并且了解到我们现在无法提供有效的服务器解决方案。 不久前,我们收购了Multiplay公司,以便为Unity游戏提供高质量的托管服务。 我们分别进行网络连接,并分别致力于优化引擎,以便可以抛弃更多东西。 因此,当所有这些融合在一起时,我们将提供出色的多人游戏解决方案。
通过Pixonic DevGAMM进行更多对话