ECS 简略版说明三:Entity command buffers

EntityCommandBuffer用于在主线程执行job中不能进行的结构变化操作,如创建、销毁实体,添加或移除组件。它提供了与EntityManager类似的方法,并支持多播放回放。Jobsafety涉及每个EntityCommandBuffer的jobsafetyhandle,保证线程安全。Temporaryentities的ID在命令执行前是临时的,在回放后会被映射到真实实体。ParallelWriter用于并行job的安全记录,通过sortkey确保命令的回放顺序。Multi-playback允许命令多次回放。EntityCommandBufferSystem则自动化了命令的回放和处理。

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

目录

Entity command buffers

Job safety

Temporary entities

EntityCommandBuffer.ParallelWriter

Multi-playback

EntityCommandBufferSystem


Entity command buffers

EntityCommandBuffer. 用来在main thread 上执行 job 里面不能执行的 structural changes (i.e. create entities, destroy entities, add components, or remove components). 操作。记录的command在调用 Playback() 方法后执行

EntityCommandBuffer有许多(但不是全部)与EntityManager相同的方法:

EntityCommandBuffermethodDescription
CreateEntity()Records a command to create a new entity. Returns a temporary entity ID.
DestroyEntity()Records a command to destroy an entity.
AddComponent<T>()Records a command to add a component of type T to an entity.
RemoveComponent<T>()Records a command to temove a component of type T from an entity.
SetComponent<T>()Records a command to set a component value of type T.
AppendToBuffer()Records a command that will append an individual value to the end of the entity's existing buffer.
AddBuffer()Returns a DynamicBuffer which is stored in the recorded command, and the contents of this buffer will be copied to the entity's actual buffer when it is created in playback. Effectively, writing to the returned buffer allows you to set the initial contents of the component.
SetBuffer()Like AddBuffer(), but it assumes the entity already has a buffer of the component type. In playback, the entity's already existing buffer content is overwritten by the contents of the returned buffer.
📝 NOTE
有些方法没有,是因为有些操作不需要延迟执行,即在command buffer里面执行
在调用 played back 方法之后, an EntityCommandBuffer instance 就不能再使用了. 如果需要继续记录,需要创建一个新的,独立的 EntityCommandBuffer instance.

Job safety

每一个EntityCommandBuffer 都有一个 job safety handle,和每一个commponent 一样

  • EntityCommandBuffer还正在被job 使用,在主线程上调用EntityCommandBuffer的方法
⚠ IMPORTANT
不推荐使用 EntityCommandBuffer.ParallelWriter跨多个并行job使用, it’s virtually always best to create and use one EntityCommandBuffer per job.

Temporary entities

EntityCommandBuffer的方法CreateEntity() or I nstantiate() 在命令执行完之前,不会创建新的实体,所以返回的 entity ID 是 temporary ID, 值是负的,同一个EntityCommandBuffer的方法 AddComponentSetComponent, and SetBuffer将会使用 temporary ID's. In playback,命令执行完之后, temporary ID's 会重新映射到一个真实的实体上。

EntityCommandBuffer.ParallelWriter

To safely record commands from a parallel job, we need an EntityCommandBuffer.ParallelWriter, which is a wrapper around an underlying EntityCommandBuffer.

ParallelWriter has most of the same methods as an EntityCommandBuffer itself, but the ParallelWriter methods all take an additional 'sort key' argument for the sake of determinism:

When an EntityCommandBuffer.ParallelWriter records commands in a parallel job, the order of commands recorded from different threads depends upon thread scheduling, making the order non-deterministic. This isn't ideal because:

  • Deterministic code is generally easier to debug.
  • Some netcode solutions depend upon determinism to produce consistent results across different machines.

While the recording order of the commands cannot be deterministic, the playback order can be deterministic with a simple trick:

  1. Each command records a 'sort key' integer passed as the first argument to each command method.
  2. The Playback() method sorts the commands by their sort keys before executing the commands.

As long as the used sort keys map deterministically to each recorded command, the sort makes the playback order deterministic.

So in an IJobEntity, the sort key we generally want to use is the ChunkIndexInQuery, which is a unique value for every chunk. Because the sort is stable and because all entities of an individual chunk are processed together in a single thread, this index value is suitable as a sort key for the recorded commands. In an IJobChunk, we can use the equivalent unfilteredChunkIndex parameter of the Executemethod.

Multi-playback

EntityCommandBuffer 创建的时候选择PlaybackPolicy.MultiPlayback ,它的Playback方法可以被调用多次,否则会报错, Multi-playback 在对实体执行多次相同的操作时,很有用

EntityCommandBufferSystem

EntityCommandBufferSystem 提供了一种方便的方式执行EntityCommandBuffer playback.   EntityCommandBufferSystem 创建的 EntityCommandBuffer 会在下次 updates 的时候 playback 、dispose

You rarely need to create any EntityCommandBufferSystem's yourself because the automatic bootstrapping process puts these five into the default world:

  • BeginInitializationEntityCommandBufferSystem
  • EndInitializationEntityCommandBufferSystem
  • BeginSimulationEntityCommandBufferSystem
  • EndSimulationEntityCommandBufferSystem
  • BeginPresentationEntityCommandBufferSystem

The EndSimulationEntityCommandBufferSystem, for example, is updated at the end of the SimulationSystemGroup. (Notice there's no EndPresentationEntityCommandBufferSystem at the end of the frame, but you can use BeginInitializationEntityCommandBufferSystem instead: 一帧的结束和下一帧的开始在逻辑上是同一时间点).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TO_ZRG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值