DOTS介绍+UnityDOTS-MAN⼩游戏项⽬实战
⽂章⽬录
前⾔
DOTS是Unity在17年左右提出的⼀个概念,其核⼼是ECS。
提⽰:以下是本篇⽂章正⽂内容,下⾯案例可供参考
⼀、1. What is DOTS and why we use it?
全称:(Multi-Thread)Data-Oriented-Tech-Stack
(多线程式)数据导向型技术堆栈
1.DOTS包含的主要元素(三件套)
1. 实体组件系统(ECS) - 提供使⽤⾯向数据的⽅法进⾏编码的框架。在Unity中它通过Entities软件包进⾏分发,您可以通过Package
Manager来添加编辑器。
2. C#作业系统 (JobSystem)- 提供⼀种⽣成多线程代码的简单⽅法。它通过Jobs软件包进⾏分发。
3. Burst编译器 - 可⽣成快速、优化的本机代码。它通过Burst软件包进⾏分发,可通过Package Manager在编辑器中使⽤。
4. 本机容器 - 属于ECS数据结构,可提供对内存的控制,值得注意的是Unity专门对内存管理进⾏了⼀部分优化以降低MissCache。2.Why we use it?
1. 许多并⾏编程范式,尤其是SIMD(单指令多数据)型范式,更倾向于使⽤SoA(结构体数组)。在CUDA C编程中也普遍倾向于SoA,
⼀维数据元素是为全局内存的有效合并访问⽽预先准备好的,⽽相同内存操作引⽤的同字段元素在存储时时彼此相邻的,使⽤SoA能够显著减少MissCache。
2. 实体组件系统(ECS)提供了⼀种⾯向数据的编码设计⽅法。利⽤⾯向数据的⽅法,可以对数据结构加以组织,以免出现⾼速缓存未命
中的情况,从⽽令随后的数据访问更加⾼效、快捷。由于⾯向对象的设计并不专注于数据的组织,因此⾼速缓存未命中的情况很常见,这样就减慢了CPU访问数据的速度,因为它必须频繁地返回访问主内存中的数据。
3. C#作业系统可以轻松地⽤C#编写快速、并⾏化的代码,以充分利⽤当今的多核处理器。
4. Burst编译器会⽣成⾼度优化的代码,⽽这些代码可以利⽤您要编译的平台硬件。
Tips:
1. jobsystem和ecs是两个不同的东西,但是配合起来使⽤会有1+1>2的效果
2. burst与ecs的⾼度适配也使得ecs运⾏效率很⾼
3.Where we use it? (摘⾃Unity官⽅)
除⾮您在寻求短期或中期的性能改进,否则很难判定是否需要过渡到DOTS或何时过渡到DOTS。
DOTS⼏乎可以为每个应⽤程序带来⼀定程度的性能改进。这其中包括性能、电池使⽤寿命、迭代及项⽬可扩展性。过渡到DOTS不会造成任何性能的下降,但评估过渡到DOTS所增加的费⽤却⾄关重要,尤其是对于那些仅带来较⼩改进的项⽬。 对于所有应⽤程序⽽⾔,DOTS 适合处理⼤量数据,例如开放式环境或使⽤⼤量相同材料的复杂结构。通过在实例之间共享公共数据以减少内存访问,DOTS也同样适⽤于重复的元素。 DOTS将来会帮助您开发⾼质量的内容,⽽不使⽤DOTS的Unity却很难做到,这⼀点务必要考虑清楚。例如,当今的标准游戏和Unity项⽬已经取代了过去的AAA游戏。
放眼未来,您需要采⽤DOTS来保持竞争⼒。 针对不同的垂直⾏业,DOTS可以适⽤于不同的解决⽅案:
(1)对于AEC(⼯程建设)应⽤
DOTS适合处理⼤型数据集并确保内容的可扩展性。
DOTS⾮常适合进⾏⼤型交互式地图和具有⼤量模型和重复内容(例如建筑物和道路)的环境设计。
DOTS适⽤于复杂的⼯程可视化,可⼤规模地模拟现实环境。例如,DOTS⾮常适合进⾏粒度级⼯⼚和基础架构设计。
(2)对于汽车应⽤
⾃动驾驶的仿真和可视化
DOTS⾮常适合进⾏⼤型交通和⾏⼈模拟,这需要成千上万的志愿Agent以逼真的⽅式移动和交互。
(3)对于游戏独⽴开发者和⾃由职业者
DOTS可以帮助您减轻游戏中⼀些⾼成本操作的负担,并有助于提⾼性能,尤其是对于⼀些重复性进
程。
许多轻量级游戏(例如⽤于移动设备的游戏)并不能最⼤限度地提⾼硬件性能。即使有些游戏能够做到这⼀点,但这可能并不是它的主要关注点。不过,随着游戏的不断发展和硬件需求的持续增加,明智的做法是为将来使⽤DOTS做好准备。同样,Project Tiny也提供了使⽤DOTS开发较⼩应⽤程序和游戏的解决⽅案。
如果您没有使⽤DOTS的迫切需求,那么最好先未⾬绸缪,提⾼⾃⼰的DOTS技能,以便在DOTS成为Unity开发的标准⽅法时能够整装待发。
(4)对于游戏⼯作室
当前格式的DOTS可以帮助您逐步达到Unity或其他⽅式所⽆法达到的规模和性能。具体⽽⾔,更长的电池使⽤寿命、温度控制以及DOTS所提供的代码可重⽤性是其主要优势所在。这些⽅⾯的性能改进还使您可以开发更多的低端设备,尤其是在西⽅市场以外的地区,这些设备会受到⼀定的硬件限制。
通过让研发团队以DOTS开展⼯作,可以帮助您逐步了解所能采取的最佳⽅法,以及哪些最新的功能和领域最具性能优势和发展影响⼒。
DOTS并⾮要取代引擎团队的作⽤,⽽是让⼯程师腾出更多精⼒在⾃⼰的专业领域(例如阴影或着⾊
器)进⾏创新。
4.DOTS的优劣(机遇以及风险)
在改善Unity项⽬的绩效⽅⾯,DOTS有着巨⼤的潜⼒。 但是,在使⽤DOTS时需要做出⼀些考量,它们会影响到项⽬的时间表、预算和开发团队。以下是⼀些需要与项⽬优先事项进⾏⽐较和对⽐的事项。这些事项可以归类为风险与机遇。
机遇
1. 改进性能。默认情况下,我们经常使⽤“性能”⼀词来描述DOTS。这是什么意思呢?借助⾯向数据的设计和多线程,DOTS可以显著
提升内存、运⾏时间和电池性能。随着游戏中显⽰的项⽬数量不断增加,提⾼性能的潜⼒也随之上升。相反,对于项⽬较少的游戏,您会发现游戏性能的改善程度却不太明显。
2. 代码控制。随着项⽬规模的不断增⼤,DOTS可以更好地控制代码的复杂性。为DOTS编写的代码通常可以更好地分离关注点。因此,
使⽤DOTS⼯作时,代码重构、编写单元测试以及在开发⼈员之间分配⼯作就变得更加容易。
风险
1. 学习成本。如果您不熟悉DoD,那么⾯对DOTS时就会有⼀个学习曲线。尽管DoD在计算机科学领域有着良好的根基并已存在数年,
⽽且DoD⽅法与OOP⽅法也有很⼤的不同,但DoD本质上并不⽐OOP复杂。ECS是⼀种不同于当前Unity MonoBehaviour⽅法的代码体系架构,因此学习需要⼀定的时间。⽬前,我们认为⼀名普通的Unity专业开发⼈员平均需要1个⽉才能熟练使⽤DOTS。这⼀准备时间可以被使⽤DOTS时的代码质量和性能改进所抵消。当然,具体要取决于项⽬。
2. 有限⽀持。DOTS当前仅与Unity中⼀组有限的功能兼容。 最终,DOTS将与Unity的所有功能完全兼容,但我们⽬前尚⽆实现完全兼
容的时间表。不过,DOTS允许在单个项⽬中同时使⽤游戏对象和DOTS,因此您可以将DOTS⽤于最频繁的处理任务,⽽将⾮DOTS Unity⽤于其余任务。
3. 过渡。如果之前的项⽬是基于Mono开发,那么跟ECS之间的转换可能⽐较简单,使⽤Unity⾃带的⼀些Hybrid⼯具就可以较为简单的
做到,但是想要把ECS转化为⽬前常⽤的Mono的话,我们认为可以做到,但是⼗分困难,⽽且也不建
议这么做(为什么要尝试把⾼效率转为低效率呢)。⽬前⽐较推荐的是HybridECS开发,ECS与Mono混合在⼀起,ECS再配合Jobsystem处理最需要多线程的那⼀部分。
随着时间的推移,晶体管电路逐渐接近性能极限,在摩尔定律逐渐失效的今天,⼈们⾯临的数据也呈⼏何倍数暴增,我们有理由去发明并且学习使⽤⼀种效率更⾼,更能完全发挥硬件性能的软件编程⽅式,⽬前看来也许ECS也许能做到。
⼆、DOTS-Man⼩游戏项⽬实战
想要熟悉DOTS以及ECS框架,最好还是要上⼿做⼀个⼩项⽬,使⽤部分基础组件,想要熟悉以及精通还需要⼤量的练习以及使⽤,开发过程中要配合官⽅Entities⽂档使⽤。
1.环境配置
如果是Unity2020.X以下版本:
1. windows -> package manager
2. advanced -> show preview package
3. install三件套 (Entities,Jobs,Burst)
rotate属性4. install其他组件(Hybrid Renderer,Mathematics)
如果是Unity2020.X及以上版本(推荐,作者使⽤2020.3.26f1c1):
进⼊package manager
点击 + 号点击add package from gir url⼿动添加三件套以及其他组件
com.unity.dots.editor
com.unity.physics
ities
dering.hybrid
2.游戏设计
我们准备做⼀个类似Pac-Man的⼩游戏,主要熟悉Physics包以及Entities的基本使⽤,所以不会开发怪物AI之类的,因为使⽤DOTS 开发所以就叫DOTS-MAN好了。
需求分析
主要功能有:玩家移动,镜头跟随,分数显⽰,因为如果⽤ECS来修改UGUI的TEXT可能⽐较⿇烦,
这⾥选择使⽤HybridECS开发,使⽤MonoBehaviours开发⼀些基础功能⽐如镜头跟随以及物体⽣产之类。
3.正式开发
⼀些⾃带脚本
在开发过程中,因为收集物以及玩家还有地形之类的都要有碰撞,但是ECS⽆法使⽤object上⾯的collider之类的组件,所以就要⽤Entities 包⾃带的⼀些脚本。
记得在挂Entities脚本之前删掉不⽤的Object脚本,避免混淆以及⽆意义的空间占⽤
把Object转化成Entity的脚本:
⼀般配合⼀起使⽤的脚本就是PhysicsShape和PhysicsBody,⼀个控制物理碰撞的类型,⼀个控制entity的物理性质(例如重⼒之类的),各个属性的作⽤都有明确说明:
添加physicsbody之后碰到List越界报错问题解决⽅案:
go into YOURPROJECTLibrary/PackageCache/
copy llections@0.15.0-preview.21 into YOURPROJECT/Packages/
open llections@0.15.0-preview.21\Unity.Collections\NativeList.cs
change line 599 from Allocator.None to Allocator.Invalid
Component
组件只有三个,两个存储分别存储移动和旋转的速度,⼀个负责标记收集物(所以⾥⾯没有数据)
要记得把Serializable属性改为GenerateAuthoringComponent,这样把component挂上object之后就会把他变成entity。创建component和system都可以直接使⽤右键 -> create -> ECS进⾏快速选择⾃带模板
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论