DOTS介绍+Unity DOTS-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文档使用。
Entities最新版本0.17的官方说明文档

1.环境配置

  • 如果是Unity2020.X以下版本:
    1. windows -> package manager
    2. advanced -> show preview package
    3. install三件套 (Entities,Jobs,Burst)
    4. install其他组件(Hybrid Renderer,Mathematics)

在这里插入图片描述

  • 如果是Unity2020.X及以上版本(推荐,作者使用2020.3.26f1c1):

    • 进入package manager
    • 点击 + 号点击add package from gir url手动添加三件套以及其他组件
      • com.unity.dots.editor
      • com.unity.physics
      • com.unity.entities
      • com.unity.rendering.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 com.unity.collections@0.15.0-preview.21 into YOURPROJECT/Packages/
open com.unity.collections@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进行快速选择自带模板
在这里插入图片描述

using Unity.Entities;

[GenerateAuthoringComponent]
public struct MoveComponent : IComponentData
{
   
    public float moveSpeed;
}
using Unity.Entities;

[GenerateAuthoringComponent]
public struct RotationComponent : IComponentData
{
   
    public float rotateSpeed; 
}

Component配置:
玩家:
在这里插入图片描述
墙体和收集物:

要注意在脚本中配置Collision Filter相关以及Collision Response相关,即某个entity属于哪个标签,他能与其他哪些标签的entity发生碰撞

在这里插入图片描述
搭建一个使用场景(renderer相关的根据自己喜好来整):

因为mono和ECS是相互穿插的,所以如果mono中有需要的system可以直接先去看看system的代码,配合官方文档理解为何这么做,这样才能把整个流程梳理清楚(至少我学习的时候是这样的)

Mono Behaviour

这里需要一个全局的mono behaviour来控制游戏,例如entity与object的连接,这里我们换一种方式,把之前的玩家小球弄成prefab,然后在这个全局mono控制玩家的生成,起名就叫做GameManager吧(具体说明看注释):

  1. GameManager:
using System.Collections;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine.UI;
using Unity.Transforms;

public class GameManager : MonoBehaviour
{
   
    public static GameManager instance;

    public bool insaneMode;

    //在实体object世界中的prefab
    public GameObject ballPrefab;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值