目前程序开发分为:面向过程开发(c 语言 ),面向对象开发( unity传统开发方式 ),面向数据开发(ECS)大致这三种。Unity官方2018开始,推出了DOTS(多线程式数据导向型技术栈),其中分别用到的技术:ECS 、Jobs System、Burst 。

首先要明白UnityECS开发方式和传统开发方式区别是如何提高游戏性能的:

 

传统的GameObject系统:

UnityECS unityecs opp_System

传统开发方式主要用到:

1.GameObject(场景物体)

2.Transform、Rigidbody等组件(Component)

3.各种脚本(Script)

UnityECS unityecs opp_UnityECS_02

这三者之间都是通过内存引用来相互连接。

优点:方便开发。

缺点:对象与组件之间通过地址引用,并且它们在内存上过于分散,那么查找的时候在性能上会有缺陷。另外当引用组件的时候,还会引用着一些不需要的数据。列如控制小球旋转信息(Rotation),但是不需要小球的位移信息(Position),这就会造成一些不必要的加载,况且当数据以大数量级加载时,优化此方面会大大提高性能。

下图传统Gameobject的内存引用图:

UnityECS unityecs opp_github_03

最新的UnityECS框架:

UnityECS(实体组件系统)系统分为:

    实体 Entity:数据组件的集合,是包含唯一ID的对象。

    组件数据 Component Data:主要存储在实体中的数据 (不包含处理逻辑)。

    组件系统 ComponentSystem: 定义游戏行为和逻辑。

UnityECS unityecs opp_github_04

UnityECS unityecs opp_github_05

 

 

数据(ComponetData)和行为(System)是区分开的,每个实体(Entity)都有自己的N个数据自己来保存,自己有自己的身份证(ID)来供别人区分,让别人通过不同的筛选器(group)选择要操作的实体,并通过调用不同的行为(System)来改变该实体的数据。

group主要提供不同的查询方式给你提供你要修改哪些数体的数据,可以类比数据库的使用。

按照这种格式开发,各个对象、组件在内存中都是按照顺序排列的,提高缓存效率,缩短访问时间。

为啥数据连续排列就能提高性能?

    1.利用PCU的多级缓存技术,提高访问速度。

        特别是空间局部性:如果某个数据被访问,那么与它相邻的数据很快也能被访问。

    2.利用CPU的SIMD(单指令流多数据流技术)

        说白就是利用CPU多核并发技术进行并行计算( 也就是多线程开发,传统开发Upate等都是单线程的,像物体移动,彼此每个物体之间不需要数据依赖可以通过并行计算提高速度。尤其适用于移动端)

 

unity ECS系统 ,发现网上有官方框架和非官方框架的学习路线:

第一种是Entitas(由OYM在Github开源项目):

优点:通用的体系,可以将这套体系快速重构代码,不仅适用于Unity,也可以对服务器使用这套框架,

缺点:性能永远是Unity的ECS系统的50%,学习曲线非常陡峭。

github地址:https://github.com/OneYoungMean/Entitas-CSharp-OYM/wiki

 

第二种是UnityECS (Unity官方提供的框架):

优缺点从第一种比较可以看出。官方提供的ECS框架,其中迭代了几十个版本API删除和增加,官方提供的案例有的也不能正常运行,这会造成有很高的学习成本。

ECS主要适用于大型场景、数量级的游戏物体的场景,比如 僵尸世界大战的尸潮 等。当然,你的游戏项目并不是这种类别,使用ECS框架也是能提高你的游戏性能。ECS框架可以想象类似MVC框架一样,让你以对应格式去写代码,并了解面向数据的开发方式。

文档:https://docs.unity3d.com/Packages/com.unity.entities@0.1/manual/index.html

官方仓库:https://github.com/Unity-Technologies/EntityComponentSystemSamples

注意:UnityECS官方迭代速度太快有些API已经不适用,官方文档会报错,据说2020年Unity会推出ECS的一个大版本。

 

Jobs System:

unity官方早就推出了也适用于传统开发方式,目前Jobs System和ECS强强联合更能够提高游戏的性能!Jobs System是多核开发技术,untiy自己提供了job概念,不需要你自己去处理线程池切换等,只需要向job中添加处理逻辑。

详情可以参考:https://software.intel.com/es-es/node/796085

Burst:

Burst是一个编译器,它使用LLVM将IL / .NET字节码转换为高度优化的本机代码。


本篇参考文章:

Unity DOD (ECS) 基础概念与资料汇总:https://indienova.com/indie-game-development/unity-dod-all-in-one/

远程项目仓库(github):https://github.com/h1031464180/UnityECS