2

我正在尝试在并行作业中访问实体组件数据。组件数据的类型为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;但没有改变。

任何帮助或解释将不胜感激!

4

1 回答 1

1

编辑(解决方案):就我而言,问题是与我在项目中拥有的自定义 ReadOnly 属性发生冲突。我摆脱了我的自定义属性,现在一切正常。

我遇到了同样的问题,并启动了一个 Unity 论坛主题,遗憾的是,它受到了与这个问题一样多的关注。

https://forum.unity.com/threads/readonly-errors-when-trying-to-use-componentdatafromentity.824799/

我开始怀疑 ComponentDataFromEntity 只是在 ForEach 工作中不受支持,但无法亲自确认,也不知道谁可以。

于 2020-02-11T00:41:41.127 回答