我正在尝试在并行作业中访问实体组件数据。组件数据的类型为PheromoneComponent
。定义作业的结构如下所示:
[UpdateBefore(typeof(PheromoneTrailsSystem))]
public class MovementSystem : JobComponentSystem
{
private EndSimulationEntityCommandBufferSystem endSimulationEntityCommandBuffer;
protected override void OnCreate()
{
endSimulationEntityCommandBuffer = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
base.OnCreate();
}
[BurstCompile]
struct MovementSpeedJob : IJobForEachWithEntity<Translation,Rotation, MovementComponent, QuadrantEntity, AntComponent>
{
[ReadOnly] public float dT;
[ReadOnly] public Unity.Mathematics.Random randGenerator;
[ReadOnly] public long currentTimestamp;
[ReadOnly] public int mapSizeHeight;
[ReadOnly] public int mapSizeWidth;
[ReadOnly] public NativeMultiHashMap<int, QuadrantData> quadrantMultiHashMap;
[ReadOnly] public ComponentDataFromEntity<PheromoneComponent> pheromoneDataArray;
//[NativeDisableParallelForRestriction] ComponentDataFromEntity<PheromoneComponent>
pheromoneDataArray;
public EntityCommandBuffer.Concurrent entityCommandBuffer;
public void Execute(Entity entity, int index, ref Translation translation, ref Rotation
rotation, ref MovementComponent movementComponent, ref QuadrantEntity quadrantEntity,
ref AntComponent antComponent){......}
该作业使用以下实例执行:
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var job = new MovementSpeedJob()
{
dT = Time.deltaTime,
randGenerator = new
Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1,100000)),
currentTimestamp = DateTime.Now.Ticks,
mapSizeHeight = GameState.GetMapSizeHeight(),
mapSizeWidth = GameState.GetMapSizeWidth(),
quadrantMultiHashMap = QuadrantSystem.quadrantMultiHashMap,
entityCommandBuffer =
endSimulationEntityCommandBuffer.CreateCommandBuffer().ToConcurrent(),
pheromoneDataArray = GetComponentDataFromEntity<PheromoneComponent>(true)
};
JobHandle jobHandle = job.Schedule(this, inputDeps);
endSimulationEntityCommandBuffer.AddJobHandleForProducer(jobHandle);
return jobHandle;
代码运行,但每次调用更新时我都会收到以下错误消息:
InvalidOperationException: The native container has been declared as [WriteOnly] in the job,
but you are reading from it.
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x1ba8eccc0 + 0x00052> in <85963591c1a04aad836445db604e7807>:0
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Jobs/AtomicSafetyHandle.bindings.cs:148)
Unity.Entities.ComponentJobSafetyManager.CompleteWriteDependency (System.Int32 type) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentJobManager.cs:386)
Unity.Entities.EntityManager.GetComponentData[T] (Unity.Entities.Entity entity) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/EntityManagerAccessComponentData.cs:42)
AntBehaviourSystem+ExcretionJob.Execute (Unity.Transforms.Translation& translation, Unity.Transforms.Rotation& rotation, QuadrantEntity& quadrantEntity, AntComponent& antComponent) (at Assets/Scripts/Ant/Systems/AntBehaviourSystem.cs:39)
Unity.Entities.JobForEachExtensions+JobStruct_Process_CCCC`5[T,T0,T1,T2,T3].ExecuteChunk (Unity.Entities.JobForEachExtensions+JobStruct_Process_CCCC`5[T,T0,T1,T2,T3]& jobData, System.IntPtr bufferRangePatchData, System.Int32 begin, System.Int32 end, Unity.Entities.ArchetypeChunk* chunks, System.Int32* entityIndices) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/IJobForEach.gen.cs:3576)
Unity.Entities.JobForEachExtensions+JobStruct_Process_CCCC`5[T,T0,T1,T2,T3].Execute (Unity.Entities.JobForEachExtensions+JobStruct_Process_CCCC`5[T,T0,T1,T2,T3]& jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/IJobForEach.gen.cs:3541)
由于我从未明确定义过,ComponentDataFromEntity
因为[WriteOnly]
这个错误似乎表明并行工作中存在一些冲突。我ComponentDataFromEntity
是否正确通过?还有其他我不知道的陷阱吗?我还有其他一些正在运行的工作,PheromoneComponent
但我尝试禁用它们并且错误仍然存在。此外,我猜 ECS 作业系统应该注意在执行另一个作业之前完成所有作业依赖项。
我也尝试过[NativeDisableParallelForRestriction] ComponentDataFromEntity<PheromoneComponent>
而不是[ReadOnly] public ComponentDataFromEntity<PheromoneComponent> pheromoneDataArray;
但没有改变。
任何帮助或解释将不胜感激!