Unity DOD (ECS) 基础概念与资料汇总
April 01, 2021https://indienova.com/indie-game-development/unity-dod-all-in-one/
引言
这两周基本完成了现阶段的 Unity DOD 的学习了,今天开始要真正开始改造我的项目。所以在此之前稍微总结一下,给自己加深个记忆,顺便可能也能帮助到有兴趣的同学。我不会提及技术细节,只是对现有的学习资料进行一个简介,给出我认为合理的学习顺序,我觉得比起用我自己蹩脚的语言复述教学,这些才是更有用的东西。
但是一定要注意 DOD 的各个组件会在2019年的一年时间内才会逐渐稳定发布。如果你手头就有紧迫上线的项目的话,还是不要急于应用。
首先,你可能一脸懵逼的问”DOD”是啥,你不是说要学 ECS 么。 事实上这正是我觉得有必要总结的一个原因。 当我刚开始研究的时候我还只认识到 Unity 在强推新的 ECS (Entity Component System) 即实例组件系统。我把它视为跟我正在用的 Entitas 类似的 ECS 框架而已。虽然当时我已经知道 Job System 和 Burst Compiler,但是我并没有意识到三者之间的联系是多么紧密。
什么是 DOD
Unity 实际上在做的大计划,是一个在程序届流行了一阵子,最近越来越火的概念 DOD (Data Oriented Design) 即 面向数据设计。他是与我们所熟知的 OOD (Object Oriented Design) 即面向对象设计相对的概念。目前的流行程度甚至于你用 youtube 一搜就会发现:
https://www.youtube.com/results?search_query=data+oriented+design
在截图里第一条搜索结果的 Mike Acton 大佬,目前正供职于 Unity 并且正是 Unity 的 DOD 改革主导者之一.然后第三条则是大名鼎鼎的吹哥在自己正在设计的新游戏语言开发直播里讲解 DOD。虽然我认为还不至于说”OOP 已死,DOD 永生”这么极端,不过其红火程度可见一斑。
Unity 的 DOD
https://youtu.be/NF6kcNS6U80?t=757
说回 Unity, 如图,这是摘自 Unity at GDC 2018上的一帧 Slide, 表达了 Unity DOD 计划的全貌,其全新的组成部分是从上到下是以下几个: ECS, Job System, HPC#, Burst Compiler。
ECS
实例组件系统,是编程思想的改变,从基于对象的运作,改变为”流水线式运作”(我自己的比喻)。虽然显然破坏了”程序对现实的模拟”这样美好的愿望,但是却大大的增强了解耦性,可测性,扩展性。并且天然是以下要描述的几个组件的好伙伴~
Job System
Job System 是 Unity 对 CPU 多核编程的应用。通过把工作分散到 CPU 的各个核心上来大大提升运行效率。而 ECS 跟他之间的搭配则是由于 ECS 的 System 部分天然是以批量处理为核心的,因此只要稍加改动,就可以转变为批量的分 Job 交到多核去处理。实现性能的提升。
HPC#
HPC#(High Perform C#)是 Unity 开发的一个 C#子集,通过抛弃对象,指针,等高级特性,从语言层面加速性能。 截图里没有直接列出这个,但是 NativeContainer 是 HPC#的一环。 而由于 ECS 本身的去对象化,可见又是天然的好伙伴。
Burst Compiler
这又是 Unity 自己开发的,一个全新的快速编译器,最重要的是由于不用考虑通用性,仅仅针对 Unity,针对游戏,再配合 HPC#, 使得性能有了更大的提升。由于牵扯到编译器层面,这个部分我的理解是最薄弱的,如有错误敬请指正。
合体
于是当四个部分一起合力时我们会得到什么样的结果呢?参见刚刚过去的 Unite LA 2018 的演示https://www.youtube.com/watch?v=O5F30NEJvrU
在官方 Unity DOD 教程里则给出了经典方式同屏 18000 单位,DOD 方式 104000 单位的近乎6倍的性能提升。当然我们的实际游戏会基于游戏内容的不同,以及组件的复杂性未必能有这样的极端结果,但我想2-3倍的性能提升还是可以预期的。
学习材料
然后就是最主要的目前阶段如何学习了。 通过这两周的学习,我的认识是:目前的学习材料杂乱无章并且容易过期。原因很简单就是现在都只是在 preview 阶段,很多东西都在快速变更中,尤其 API 里,对一个需求还会存在多种实现方式,官方希望在试用者们的反馈下最终再确定到其中一种,因此你现在写的代码和看的教程很可能会很快无效。甚至18年下半年的大会上出现的一些代码标签,都已经和上半年的不一样了。 官方也显然没有精力维护一个系统性的教学。因此我认为我把我现在所学到的材料按照我自己认为合适的学习曲线去归纳一下并且排序列出是非常有必要的。
ECS 入门
我建议首先不要考虑 Unity, 而是先单纯对 ECS 有一个基本的学习,首推这两篇文章:
- 然后是 https://www.richardlord.net/blog/ecs/what-is-an-entity-framework.html结合游戏引擎的实际需要,更为详细的介绍。
官网教程
然后回到 Unity 这边,官网教程的 6 个视频是比较好的入门:https://unity3d.com/cn/learn/tutorials/topics/scripting/introduction-ecs?playlist=17117但是非常浅,在一个简介之后,就是我前文说过之后的同屏小飞机数量对比的项目教程,甚至到最后都没有给出最终版本的源码=.=,我想跟着写,但是发现到最后的 ECS 版本写不下去,因为相关的 System 只给出了最具代表性的一个作为例子展示。
官方 Sample
地址在 https://github.com/Unity-Technologies/EntityComponentSystemSamples,基本上是官方目前除了演讲视频外,最主要教学内容了。
拉下来后会看到里面有七八个例子,直接看的话感觉很散乱,虽然有附文档,但是我当时硬啃了很久还是比较缺乏头绪。但是如果配合下面的各个演讲视频看的话,会有奇效。
在第三方教程方面我发现这个哥们 Charles Amat 的博客里有很多视频教学,如果你想立即上手而不是先看一大堆理论教学的话,可以直接来看他的博客。但是要注意这里是纯应用角度的,你可能并不会像看官方演讲那样对内部有很深入的了解。并且不保证会随时根据 Unity 的变化来更新旧内容。
接下来是上半年的 Unity at GDC 2018的五场相关演讲了,事实上2017年的时候已经有过几个相关演讲,但是其一是因为推介性质为主,其二是由于 API 的快速变更,我觉得已经不太具有教学意义。
Unity 的 CTO, Joachim Ante 大佬对 UnityDOD 战略的一个总览,后半段有个简单例子。
这场演讲口音很重,但是干货满满。 底下一堆评论在吐槽他念 job 念成 yob 233。不过说真的这场真的给我看 sample 范例解决了很多疑惑,我还做了一些要点的笔记:
Unity at GDC - A Data Oriented Approach to Using Component Systems
不愧是宣传 DOD 多年的大佬出手,是着眼于内存使用层面的一场演讲,以 Boid 示例(Samples 示例项目里有,要记得结合着一起看),让你对内存的新的使用方式有了一个深入的理解。我的笔记:
这场演讲是关于 DOD 的一个子项目 Unity Tiny 分支的演讲,目的是制作一个最轻量级的 Unity 分支内核,正好这个就在几天前官博上发布了示例项目,示例游戏只有700k 的下载容量,1.6m 的完整容量。他主要是面对互动广告,手表等端的,对我而言没有什么太大的意义。但是由于使用了 Pure ECS,并且示例项目中有一整个游戏的完整代码和测试代码(非常重要!)因此很有参考价值。
这场的主讲是一位 30 年前从汇编写起的老爷子,是 Unity 的 Burst Compiler 的主要负责人.这一点真的是感动到我了,看看国内程序员 30 岁后的命运…
不过这一讲的内容真的有点难倒我了,不时崩出来的 IR(中间码)感觉在看天书…我想说如果你是纯应用层其实可以不看,但是有时间的话让自己增加一下视野,了解一下 Unity 的底层挺好的。表示我模模糊糊的学会了一个概念”alias”~大概是指不同指针指向同一个内存位置的性能问题~
然后是下半年刚刚过去的 Unite LA 2018 的 Day 2 直播视频,这一天足足9小时的9场演讲的内容完全都是 Unity DOD 相关,可见官方推动的力度。 从内容上来说比起上半年的 GDC 的5场演讲要更为深入。因此全部应当在看完 GDC 之后再看。
由于全天所有演讲是同一个直播视频的不同段落,因此我这里只放标题上的一个链接了,在评论里有不同演讲的时间点链接。
这 9 场演讲主要立足于 Unity 本身对于 DOD 的应用以及提供的工具,我就不再一一简介了。去看就好。其中的先后顺序也不是很重要。
单元测试
最后说一下单元测试,这个东西在游戏界争议很大,我个人是站在一定要有单元测试这一派的,而 Unity 官方也是提供全面的单元测试的。因此新的 UnityDOD 如何进行单元测试,主要的学习来源就是 Unity 的源码了。 在 Package Manager 里提供的预览版 Entities 里有官方自己的单元测试,这就是首要的很好的测试学习来源。再有就是刚才说的 Unity Tiny 模式项目也有比较全的单元测试。
还有一个就是刚才说过的 Charles Amat 的视频教学了:http://infalliblecode.com/test-unity-ecs/ 但要注意的是不建议像他那样直接继承官方 ECSTestsFixture,而且官方现在版本的 test 并不发布 dll,也继承不了了。建议把 ECSTestsFixture 拷出来,理解其内容然后为己所用。
社区
对了 Unity ECS 最新内容的发布自然就在官方论坛的 ecs 区了,记得关注。
踩坑列表
最后的最后,由于当前预览版本的不稳定性,实际学习和使用的时候你一定会踩到很多坑。可以记得不时来这里看一下,说不定就找到解决方案了:
https://gametorrahod.com/unity-ecs-unit-testing-problems-with-ecs-8f31c7a37386
虽然好像是个泰国网站?不过这个哥们的采坑列表写的很全面感觉也很专业了。