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?