本文,瑞典游戏工作室Far North Entertainment将分享在传统的Unity项目中使用DOTS的经验。
我们正在使用面向数据技术栈DOTS重构Unity的核心基础。许多游戏工作室在使用C# Job System、实体组件系统ECS和Burst Compiler后,都无一例外地感受到明显的性能提升,其中就包含了瑞典游戏工作室Far North Entertainment。
在Unite Copenhagen大会上,我们与Far North Entertainment工作室的成员进行深入交流,了解他们如何在传统的Unity项目中应用DOTS功能。
Far North Entertainment
瑞典的游戏工作室Far North Entertainment是由5位来自工程研究专业的好友共同创建。自2018年初在Gear VR平台发布《Down to Dungeon》游戏之后,该公司一直致力开发一款末日僵尸生存游戏。
这款末日僵尸生存游戏的独特之处在于僵尸的数量,开发团队希望实现成千上万个饥渴的僵尸追逐玩家的效果。然而在构建原型时,他们遇到了许多性能方面的问题。
开发中主要的瓶颈在于对庞大数量僵尸的进行生成、销毁、更新和添加动画,虽然开发团队尝试了对象池和动画实例化等方法,但效果仍不显著。因此,技术总监Anders Eriksson将目光投向DOTS,从面向对象(Object-oriented)设计转为面向数据(Data-oriented)设计。
Anders Eriksson表示:促成我们思维模式发生改变的关键是停止考虑对象和对象层级,转为思考数据是如何变换和访问的。这意味着代码不必围绕具体事物来编写,不用处理过去最常见的情况。
对于同样在试着转换思维模式的开发者,Anders Eriksson的建议是:先弄清楚要解决的问题和解决方案的相关数据。是否会对相同数据集执行相同的处理过程?可以把多少关联数据打包到CPU缓存行中?如果想转换现有代码的话,那么要确定会给缓存行加入的垃圾数据量。能否将运算过程分配到多个线程上,能否利用SIMD指令?
在进一步学习后,开发团队了解到Unity组件系统的实体只是组件流中的查找ID。组件只是数据,而系统包含了所有逻辑,系统会使用称为“Archetypes(原型)”的特别组件标识来过滤实体。
Anders Eriksson表示:我们将ECS看作SQL数据库可以帮助我们更好地理解它。每个Archetype原型是一张表格,每行代表一个组件,每列代表一个独特的实体。我们可以使用系统查询这些Archetype原型表,在实体上执行操作。
开始使用DOTS
为了更好地理解,Anders Eriksson研究了实体组件系统的文档和ECS示例项目,以及Unity与Nordeus合作制作的示例项目。
此外,关于面向数据设计的学习材料也对团队有很大的帮助。CppCon 2014大会上Mike Acton关于面向数据设计的演讲开阔了他们的眼界,让开发团队了解了这种编程方式。
Far North Entertainment的开发团队在博客上发表了许多学习心得,今年9月,他们在Unite Copenhagen大会上进行演讲,介绍了转换到面向数据思维的经验。
本文的内容将以这次演讲作为基础,并且详细地讲解该团队应用ECS、C# Job System和Burst Compiler的具体方法。
排列僵尸数据
Anders Eriksson表示:我们面临的主要问题是客户端的转换信息插入,以及对上千个实体的转向信息。
开发团队最初使用面向对象的方法,编写了ZombieView脚本的抽象,它继承了更为常用的EntityView父类。EntityView是附加在游戏对象的MonoBehaviour,它会用作游戏模型的可视化展示。每个ZombieView