笨木头  2019-12-05 14:23     ECS入门     阅读(5843)     评论(2)
转载请注明,原文地址: http://www.benmutou.com/archives/2791
文章来源:笨木头与游戏开发
上一篇我们解释了最简单的ECS示例,写ECS的基本思路就是创建组件、创建实体、编写系统处理逻辑。

我们已经知道,系统是继承了ComponentSystem的类,这是最简单的系统类。

实际上,ComponentSystem有很多的缺点,在实际开发过程中,我们一般会优先使用JobComponentSystem,这样才能最大地发挥ECS的性能。

1.JobComponentSystem

我们之前所使用的ComponentSystem和以前的MonoBehaviour是非常接近的,并且都是在主线程里执行。

ComponentSystem更多的是为了让我们最低成本地把旧项目迁移到ECS模式。

 

然而,ECS最大的特点之一就是充分利用CPU,这种单线程的使用方式,并不太好。

于是,我们有了JobComponentSystem,一句话概括:我们可以简单地用多线程执行游戏逻辑。

 

我们来看看代码,组件的代码没有变化,但是,System类需要做一些改动:
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

public class RotationSpeedSystem_ForEach : JobComponentSystem { protected override JobHandle OnUpdate (JobHandle inputDependencies) { float deltaTime = Time.DeltaTime;

// Schedule job to rotate around up vector var jobHandle = Entities .ForEach((ref Rotation rotation, in RotationSpeed_ForEach rotationSpeed) => { rotation.Value = math.mul( math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * deltaTime)); }) .Schedule(inputDependencies);

// Return job handle as the dependency for this system return jobHandle; } }
 

唔…对,System变复杂了。

当然,大家都是有游戏开发经验的,理解起来应该很轻松。

 

看看现在System继承的是什么?是JobComponentSystem,Job是什么?

还记得DOTS包含哪些东西吗?



C#任务系统也就是C# Job System,利用JobSystem,我们可以更方便地利用多线程,提高游戏的性能,并且不用考虑多线程相关的烦人的事情,JobSystem帮我们搞定了。

 

从上面的代码中可以看到,OnUpdate函数发生了一些变化,这是当然的,因为我们现在继承的是JobComponentSystem:

a. OnUpdate函数需要返回一个JobHandle对象

b. 调用了Entities.ForEach后,接着又调用了Schedule函数,并返回了一个JobHandle对象

 

其他的逻辑并没有发生太多的变化,顺便一提,参数中的ref代表读写,in代表只读。

 

所以,现在的JobComponentSystem比起ComponentSystem,有什么优势呢?

优势就是利用上了C# Job System,我们不需要做太多额外的工作,就用上了多线程的功能。

 

ECS可以让我们稍微花一点点力气就享受到多线程带来的优势,如果花更多的力气,那就能获得更大的提升。

因此,ECS后续还有很多筛选实体数据的方式,我会逐一介绍。

 

注:如果你的游戏对象非常少,那么,JobComponentSystem无法给你带来太多的提升,直接使用ComponentSystem就可以了。

2.运行

除了System发生了改变,其他内容和上一篇是一样的,大家修改了System类后,运行程序,结果是一样的。

3.Entity Debuger

另外,和大家介绍一个很重要的东西,依次点击Unity菜单的Window->Analysis->EntityDebugger,可以打开ECS的调试窗口:



在运行游戏的时候,我们可以通过Entity Debugger窗口查看到实体、系统等信息:



现在可以先不管那么多,大家自己稍微看看就可以了。

 

注意,本系列教程基于DOTS相关预览版的Package包,是预览版,不代表正式版的时候也适用。

转发本系列文章的朋友请注意,带上原文链接和原文日期,避免误导未来使用正式版的开发者。
2 条评论
  • 吴霄 2020-04-22 15:51:20

    如果按以前的逻辑,我们想调试程序的话应该怎么debug去调试呢?我随便试了下,在Entities.ForEach后面那个lambda表达式里去做debug啥都打印不出来,在protected override OnUpdate里只能debug出一次,不是说应该每帧都运行吗?那不是应该每帧都打印一次吗?我觉得我可能还是没有绕出来,希望能给讲解下。
    0回复
    • 博主 笨木头 2020-04-22 18:37:24

      抱歉,我挺久没研究了(一直在等Project Tiny的正式版),如果我没记错的话,打印日志只能在主线程里进行,使用了Job的话,就不能直接打日志了。
      0回复
发表评论
粤ICP备16043700号

本博客基于 BlazorAnt Design Blazor 开发