Unity Enitity Component System 参考手册 - 2.4 System

基于0.11.1-preview 4 版本

2.4 Systems

system提供了将component的数据,从当前状态变换到其下一个状态的逻辑——例如,一个system可以通过实体的速度,乘以从上一帧到当前帧所流逝的时长,更新所有移动的entity的位置。

2.4.1 Instantiating systems

Unity ECS自动在您的项目中发现system类,并在运行时实例化它们。它将每个被发现的system添加到一个默认的 system group 中。您可以使用system attributes来指定system的parent group,以及该system在该group中的创建和执行顺序。如果未指定 parent group ,则Unity将以 确定的但未指定的(deterministic but unspecified) 顺序,将system添加到默认世界的 Simulation system group 中。您也可以使用禁用自动创建的属性。

system的更新循环,由其parent ComponentSystemGroup驱动。 ComponentSystemGroup 本身是一种特殊的system,负责更新其子system。system group可以嵌套(nested)。system从运行的世界中获取时间数据;时间数据由UpdateWorldTimeSystem方法更新。

您可以使用 Entity Debugger window 查看system配置,点击菜单:Window > Analysis > Entity Debugger 可打开此窗口。

2.4.2 System types

Unity ECS提供了几种不同类型的system。通常,为实现游戏行为和数据转换而编写的system,需要继承SystemBase类。其他具有特殊目的system类。通常应使用EntityCommandBufferSystemComponentSystemGroup类的现有实例。

  • SystemBase – 创建system时要继承的基类

  • EntityCommandBufferSystem – 为其他system提供EntityCommandBuffer的实例对象。每个默认system group在其子system列表的开头和结尾,都维护一个 Entity Command Buffer System 。这使您可以对 结构更改(structural changes) 进行分组,以使它们在框架中产生更少的 同步点(syncronization points)

  • ComponentSystemGroup – 为其他system提供嵌套的组织和更新顺序。默认情况下,Unity ECS创建多个Component System Group。

  • GameObjectConversionSystem – Editor.将在编辑器内的、基于GameObject的对象,转换为运行时的高效的entity。这个转换system在Unity编辑器中运行。

2.4.3 Creating a system

实施抽象基类SystemBase进行继承扩展,可以创建一个ECS架构的“system”系统。

要创建系统,请对必要的系统事件回调进行编程。在SystemBase.OnUpdate()函数中,执行系统必须在每一帧中完成的工作。其他回调函数是可选的。例如,您可以在OnCreate()函数中初始化系统,但并非每个系统都需要初始化代码。

系统的回调函数按以下顺序调用

  • OnCreate() – 创建系统时被调用
  • OnStartRunning() – 在第一个OnUpdate()之前,以及每当系统恢复运行时被调用。
  • OnUpdate() – 只要系统在工作时,每一帧都被执行。并且系统是Enabled。
  • OnStopRunning() – 每当系统停止更新时,这可能是因为将System的Enabled属性设置为false,或找不到与它的查询匹配的实体是被调用,在OnDestroy()函数被执行之前也会被调用。
  • OnDestroy() – when the system is destroyed. A system’s OnUpdate() function is triggered by its parent system group’s own OnUpdate() function. Likewise, when a group changes state, for example if you set the group’s Enabled property, it changes the state of its child systems. However, children can also change state independently from their parent groups. See System update order for more information.

All the system events run on the main thread. Ideally, your OnUpdate() function schedules jobs to perform most of the work. To schedule a job from a system, you can use one of the following mechanisms:

Entities.ForEach – the simplest way to iterate over ECS component data. Job.WithCode – execute a lambda function as a single, background job. IJobChunk – a “lower level” mechanism for iterating over ECS component data chunk-by-chunk. C# Job System – create and schedule general purpose C# jobs. The following example illustrates using Entities.ForEach to implement a system that updates one component based on the value of another:

public struct Position : IComponentData { public float3 Value; }

public struct Velocity : IComponentData { public float3 Value; }

public class ECSSystem : SystemBase { protected override void OnUpdate() { // Local variable captured in ForEach float dT = Time.DeltaTime;

    Entities
        .WithName("Update_Displacement")
        .ForEach(
            (ref Position position, in Velocity velocity) =>
            {
                position = new Position()
                {
                    Value = position.Value + velocity.Value * dT
                };
            }
        )
        .ScheduleParallel();
}

}