Component和Baking结束了,那接下来就是system了
System概述
System是通过使用修改Componet中的数据,达成一系列逻辑处理功能。
说白了,这里是用来写控制处理的逻辑的,比如移动,计算之类的。
System也份很多种
- SystemBase 为托管系统提供基类,最常用的一种System
- ISystem 非托管系统接口
- EntityCommandBufferSystem 为其他系统提供实体命令
- ComponentSystemGroup 提供系统的嵌套组织和更新顺序
这里我们着重说一下SystemBase和ISystem
SystemBase
使用需要继承SystemBase抽象类,并且重写OnUpdate方法
OnUpdate方法:每帧执行一次
所有的system event都在主线程上运行。最佳做法是使用该方法来计划作业以执行大部分工作。若要在System里面调用多线程执行逻辑,可以使用以下调用方法
- Entities.ForEach:循环访问组件数据。
这个方法是遍历entity和component并执行逻辑的最简单的方式。Entities.ForEach方法会根据entity查询,在所有的查询结果上执行一个lambda方法。
要执行job的lambda方法,你可以使用Schedule()和ScheduleParallel()来调度job,也可以调用Run()方法在主线程上立即执行。你也可以使用Entities.ForEach中的多个方法来设置entity查询和job选项
Entities.ForEach((Entity e, ref LocalTransform transform, in MoveComponent moveComponent) =>
{
transform.Position.x += moveComponent.Speed*UnityEngine.Time.deltaTime;
}).Run();
注意lambda参数中的ref和in修饰符。ref代表了组件会被写入,in代表组件是只读的。将组件设置为只读可以让job调度更有效率。
在使用ForEach前还可先进行筛选,利用WithAll(同时包含参数中所有组件), WithAny(包含参数中任意一个组件), WithNone(不包含参数中的组件)方法来设置更详细的筛选条件
Entities.WithAll<LocalTransform>()
.WithAny<Rotation, Scale>()
.WithNone<LocalToParent>()
.ForEach((ref LocalTransform transform, in MoveComponent moveComponent) =>
{
// 执行一些任务
})
链接: 这里有更加详细的Entities.ForEach的使用规则
- Job.WithCode:通过lambda函数构造单个后台运行的job,这种方式非常简单。Job.WithCode还可以在主线程上运行,并且还可以利用Burst编译来加快执行速度
NativeArray<float> randomNumbers
= new NativeArray<float>(500, Allocator.TempJob);
var data = 3;
Job.WithCode(() =>
{
for (int i = 0; i < randomNumbers.Length; i++)
{
randomNumbers[i] = data;
}
}).Schedule();
注意事项:产生的数据只能存储在 NativeArray 里,用于计算的数据必须是值类型,如果需要引用类型则只能使用Run方法在主线程执行。
这里也贴一个更加详细的示例
- IJobEntity:循环访问多个系统中的组件数据。
- IJobChunk:按原型块循环访问数据。
这俩我后面再研究一下。
然后是SystemBase里面提供的一些回调方法
- OnCreate:创建系统时调用。
- OnStartRunning:在第一次调用系统之前和每次系统恢复运行时调用。OnUpdate
- OnUpdate:只要系统有工作要做,就会调用每一帧。有关确定系统何时有工作要做的因素的详细信息,请参阅 ShouldRunSystem。
- OnStopRunning:在 之前调用。每当系统停止运行时也会调用,如果没有与系统的 RequireForUpdate 匹配的实体,或者系统的 Enabled属性设置为 。请注意,如果指定“否”,系统将连续运行,除非禁用或销毁。OnDestroyfalseRequireForUpdate
- OnDestroy:在系统被破坏时调用。
这些有些类似gameObject的Awake Update 这些
回调方法的执行顺序,就是按照从上到下。
先到这,下次我们再说ISystem