Unity Entity Component System --- JobComponentSystem

自动管理Job依赖是Unity中JobComponentSystem的重要特性。该系统简化了Job间的依赖管理,确保读写相同ComponentType的Jobs按顺序执行,避免数据冲突。依赖管理既保守又确定,保证逻辑的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Automatic job dependency management

自动管理Job依赖。

管理Job的依赖是件很麻烦的事。而JobComponentSystem帮我们自动处理了。规则很简单:不同系统的Jobs可以并行地访问同样类型的IComponentData。但是如果有一个Job在向该数据写操作,则这些Jobs不能并行执行,必须根据依赖调度Jobs。

public class RotationSpeedSystem : JobComponentSystem
{
    [BurstCompile]
    struct RotationSpeedRotation : IJobForEach<Rotation, RotationSpeed>
    {
        public float dt;

        public void Execute(ref Rotation rotation, [ReadOnly]ref RotationSpeed speed)
        {
            rotation.value = math.mul(math.normalize(rotation.value), quaternion.axisAngle(math.up(), speed.speed * dt));
        }
    }

    // Any previously scheduled jobs reading/writing from Rotation or writing to RotationSpeed 
    // will automatically be included in the inputDeps dependency.
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var job = new RotationSpeedRotation() { dt = Time.deltaTime };
        return job.Schedule(this, inputDeps);
    } 
}

How does this work?

所有这些Jobs和Systems声明了它们要读或写的ComponentType,因此当JobComponentSystem返回JobHandle时,它自动将对这些ComponentType的读写访问注册到EntityManager中。

因此当一个系统向A写操作,其它系统之后读取A,那么JobComponentSystem会检查列表中的读取操作,并将传递一个对第一个系统的依赖。

JobComponentSystem简单地将Jobs按照依赖关系连接到一起,简化了我们在主线程中的依赖关系管理。但是,如果一个非Job的ComponentSystem要访问这些数据呢?因为所有的数据访问时事先声明好的,因此ComponentSystem会在与其它有共同依赖的component的所有的jobs完成后,再调用它的OnUpdate。

Dependency management is conservative & deterministic

依赖管理是保守且确定的

依赖管理倾向于保守。ComponentSystem简单地跟踪用到过的EntityQuery对象并记录它们对组件类型的读写配置。

而且,当在一个System中调度多个jobs时,无论这些Jobs是否是依赖的,都要讲依赖对象传递给它们。如果证明这导致效率问题,那么尝试把该系统拆分成2个系统。

依赖管理被设计的保守,这样能够用简单的API保证逻辑的确定性和正确性。

Sync points

所有对结构的改变,都会导致“强制同步点”,如,CreateEntity,Instantiate,Destroy,AddComponent,RemoveComponent,SetSharedComponentData。这意味着这些调用发生时,之前通过JobComponentSystem调度的所有的Jobs都要完成。这是自动的。比如,在逻辑帧的执行中间,调用EntityManager.CreateEntity,会导致逻辑停下来,等待之前的Jobs 完成。

可以通过EntityCommandBuffer来避免实体创建类操作导致的Sync Points。

Multiple Worlds

每个World都有自己的EntityManager,以及互相独立的JobHandle依赖管理。一个World的Hard Sync Point,不会对另一个World产生影响。因此,对于序列化和创建对象,一个有用的建议是,在一个World中创建对象,创建好后,在一帧的开始将他们移动到另一个World中。

可以参考System update order 以及 ExclusiveEntityTransaction来避免实体创建和序列化导致的Sync Points。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值