- 中文版一图读懂ECS
- 前言
- 官方案例解析2
- 2. IJobForEach
- 小结
- DOTS 逻辑图表
- 更新计划
- 作者的话
- ECS系列目录
- ECS官方示例1:ForEach
- ECS官方案例2:IJobForEach
- ECS官方案例3:IJobChunk
- ECS官方案例4:SubScene
- ECS官方案例5:SpawnFromMonoBehaviour
- ECS官方案例6:SpawnFromEntity
- ECS官方案例7:SpawnAndRemove
- ECS进阶:FixedTimestepWorkaround
- ECS进阶:Boids
- ECS进阶:场景切换器
- ECS进阶:MegaCity0
- ECS进阶:MegaCity1
- UnityMMO资源整合&服务器部署
- UnityMMO选人流程
- UnityMMO主世界
在上一篇基于Unity2019最新ECS架构开发MMO游戏笔记0中讲了官方的第一个案例,通过图文并茂的分析,相信各位大佬已经对ECS有了一定的认识,这一篇会继续分析官方案例。 关于源码,如果有意想深入了解的,请看大鹏的专栏!
官方案例解析2开始之前的准备工作: 0下载Unity编辑器(2019.1.0f1 or 更新的版本),if(已经下载了)continue; 1下载官方案例,打开Git Shell输入: git clone https://github.com/Unity-Technologies/EntityComponentSystemSamples.git --recurse
or 点击Unity官方ECS示例下载代码 if(已经下载了)continue; 2用Unity Hub打开官方的项目:ECSSamples 3在Assets目录下找到HelloCube/2. IJobForEach ,并打开IJobForEach 场景
和第一个案例1. JobForEach中的场景一样,里面仅有四个游戏对象,那么这个案例究竟有啥子不同呢?下面一探究竟:
- Main Camera ……主摄像机
- Directional Light……光源
- RotatingCube……旋转的方块
- ChildCube……子方块
和案例1一样RotatingCube上同样挂了ConvertToEntity脚本,它将Unity的游戏对象GameObject转化成Entity,从而让游戏运行更加高效,脚本的工作原理已经在上一篇讲过了,此处跳过。 RotatingCube上还挂了另外一个脚本RotationSpeedAuthoring_IJobForEach,下面我们来看一下这个脚本:
///
/// 这就是ECS中的E了,它将数据交给C
///
[RequiresEntityConversion]//必须实体转化
public class RotationSpeedAuthoring_IJobForEach : MonoBehaviour, IConvertGameObjectToEntity
{//继承接口IConvertGameObjectToEntity,并实现Convert
public float DegreesPerSecond = 360;
///
/// 这个方法上一篇讲过,通过该方法,实体将数据交给组件储存起来
///
/// 实体
/// 目标实体管理器
/// 转化系统
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var data = new RotationSpeed_IJobForEach { RadiansPerSecond = math.radians(DegreesPerSecond) };
dstManager.AddComponentData(entity, data);
}
}
代码和上一篇的脚本RotationSpeedAuthoring_ForEach几乎一毛一样,区别在于IJob关键字上了,我猜后面一定会使用C#的Job系统,来充分利用多线程。按照流程,Entity把数据通过Convert方法传给Component组件了,下面我们来看RotationSpeed_IJobForEach 脚本:
///
/// 我啥也不干,就放数据
///
[Serializable]
public struct RotationSpeed_IJobForEach : IComponentData
{
public float RadiansPerSecond;
}
这里提一下IComponentData,它就是一个空接口而已,作用只是表面自己是Component的身份,从而让System识别,非常纯粹的一个脚本。下面是这个案例的重点RotationSpeedSystem_IJobForEach:
// This system updates all entities in the scene with both a RotationSpeed_IJobForEach and Rotation component.
///
/// 这里利用了Jobs和Burst编译器,它们和ECS共同组成DOTS,使代码运行更加高效
///
public class RotationSpeedSystem_IJobForEach : JobComponentSystem
{//通过继承JobComponentSystem来利用Jobs多线程的特性
// Use the [BurstCompile] attribute to compile a job with Burst. You may see significant speed ups, so try it!
[BurstCompile]//使用这个定语来利用Burst编译器,需要在Unity编辑器菜单栏Jobs-》Burst-》Enable Compilition来激活编译器
struct RotationSpeedJob : IJobForEach
{
public float DeltaTime;
// The [ReadOnly] attribute tells the job scheduler that this job will not write to rotSpeedIJobForEach
///
/// 该方法会在OnUpdate中每帧执行
///
/// 旋转
/// [ReadOnly]定语告诉Jobs任务系统预定器这项任务不需要写入,这样会更快速
public void Execute(ref Rotation rotation, [ReadOnly] ref RotationSpeed_IJobForEach rotSpeedIJobForEach)
{
// Rotate something about its up vector at the speed given by RotationSpeed_IJobForEach.
//Component的数据在这里使用,使方块旋转起来
rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), rotSpeedIJobForEach.RadiansPerSecond * DeltaTime));
}
}
// OnUpdate runs on the main thread.
///
/// OnUpdate在主线程上运行,上面写的旋转任务会在这里加入到计划当中
///
/// 输入依赖
///
protected override JobHandle OnUpdate(JobHandle inputDependencies)
{
var job = new RotationSpeedJob
{
DeltaTime = Time.deltaTime
};
return job.Schedule(this, inputDependencies);
}
}
和第一个案例大同小异,不过更加先进了,从1到2的过程是循序渐进的,注释还算明了吧? 下面还是按照老规格理清一下思路好了!
小结我们来对比案例一:
ECSScripts继承EntityRotationSpeedAuthoring_ForEachIConvertGameObjectToEntityComponentRotationSpeed_ForEachIComponentDataSystemRotationSpeedSystem_ForEachComponentSystem案例二:
ECSScriptsInheritEntityRotationSpeedAuthoring_IJobForEachIConvertGameObjectToEntityComponentRotationSpeed_IJobForEachIComponentDataSystemRotationSpeedSystem_IJobForEachJobComponentSystem通过上面两个对照表是不是理清开发思路了?区别在于System的迭代进化,充分利用了Jobs和Burst编译器,因此会跑得更快!
DOTS 逻辑图表上面大概表现了几者的关系,我是从表象上这么理解的,至于底层怎么弄的,I don‘t care。流程大体如下:
如果喜欢我的文章可以点赞支持一下,谢谢鼓励!如果有什么疑问可以给我留言,有错漏的地方请批评指证! 如果有技术难题需要讨论,可以加入开发者联盟:566189328(付费群)为您提供有限的技术支持,以及,心灵鸡汤! 当然,不需要技术支持也欢迎加入进来,随时可以请我喝咖啡、茶和果汁!( ̄┰ ̄*)
ECS系列目录 ECS官方示例1:ForEach ECS官方案例2:IJobForEach ECS官方案例3:IJobChunk ECS官方案例4:SubScene ECS官方案例5:SpawnFromMonoBehaviour ECS官方案例6:SpawnFromEntity ECS官方案例7:SpawnAndRemove ECS进阶:FixedTimestepWorkaround ECS进阶:Boids ECS进阶:场景切换器 ECS进阶:MegaCity0 ECS进阶:MegaCity1 UnityMMO资源整合&服务器部署 UnityMMO选人流程 UnityMMO主世界