Entities 0.14 - Handling shared NativeArray of structs

I’m writing a prototype that has agents navigating on a shared graph. The shared graph is a NativeArray of structs owned by a System. The systems that use the graph look like this:

public class SystemPathBuffer : SystemBase {
  [ReadOnly] private NativeArray<GridPos> _nav;

  protected override void OnCreate() {
    var world = World.DefaultGameObjectInjectionWorld;
    var _boardSystem = world.GetExistingSystem<SystemBoard>();
    _nav = _boardSystem.nav;
  }

  protected override void OnUpdate() {
    var nav = _nav;
    Entities.ForEach((DynamicBuffer<ComponentPathBufferElement> buffer, in ComponentAction action, in ComponentGridLocation gridLocation) => {
      Navigate(gridLocation.x, gridLocation.y, 0, 0, in nav);
    }).ScheduleParallel();
  }

  static void Navigate(int sx, int sy, int dx, int dy, in NativeArray<GridPos> nav) {
  }
}

When I run this, I get the following error:

InvalidOperationException: The previously scheduled job SystemPathBuffer:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the Unity.Collections.NativeArray`1[GridPos] <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.nav. You must call JobHandle.Complete() on the job SystemPathBuffer:<>c__DisplayClass_OnUpdate_LambdaJob0, before you can read from the Unity.Collections.NativeArray`1[GridPos] safely.

You can see that the system doesn’t write to the NativeArray. And it’s the last system in my chain of simulation systems. Also, I don’t get the same error with a NativeArray of primitive types like int.

I have a couple of questions:

  • Is there a way to let the compiler know I’m not going to write to the array? (Only a single system will do that)
  • Am I doing this totally wrong? Is there a better way to structure a shared piece of data like a navigation graph?

You need to add the .WithReadOnly(nav), like Entities.WithReadOnly(nav).ForEach(…).ScheduleParallel();

1 Like

Perfect! Thank you so much!

1 Like