I have a iComponentData called ‘Boids’. My boids are casting to find other boids (the boids have data about how to interact with each other). So I have a query for a read/write Boid container and a readonly lookup so I can lookup the other boids found by a sphere cast. I get an error saying " two containers may not be the same (aliasing)."
I can solve my problem by splitting boids into two separate components with redundant data, but I wanted to check if there’s something I’m missing that makes this possible?
Thank you
[BurstCompile]
[WithAll(typeof(SimBoidFollowerTag))]
public partial struct BoidSimulation : IJobEntity
{
[ReadOnly] public float2 LeaderPos;
[ReadOnly] public float2 LeaderVel;
[ReadOnly] public int CastGrp;
[ReadOnly] public CollisionWorld ColWorld;
[ReadOnly] public BoidConfigData configBoid;
[ReadOnly] public ComponentLookup<AgentMove2d> OtherAgentMoves;
[ReadOnly] public ComponentLookup<LoopableAgent> LoopableAgents;
[ReadOnly] public ComponentLookup<Boid> OtherBoids;
[ReadOnly] public float DeltaTime;
[BurstCompile]
void Execute(Entity entity, RefRW<Boid> boid, TransformAspect trans)
{
float2 cohesionAverage = float2.zero;
...
I guess yes, it should be safe. But it can depends on how you use lookup. Actually I wonder why there is restriction about using lookup and query component in same job.
Writing to EntityA and reading from EntityB at the same time with the same component is a race condition. EntityB could want to read from EntityA later on in the same job. Since the order is not guaranteed you end up with different results depending on wether EntityA or B did the write first.
If you are sure that you are not reading and writing to the same entities then its okay to disable safety.
An alternative is to get a copy of all the boids data (in a native array or something) and use this as your lookup data. (Double buffering, i think is the term)
Or another alternative is the use of an ‘Entity command buffer’ to apply the write change at a later stage so you don’t need the ‘RefRW’, you can make it readonly.
In most cases NativeDisable will be fine, even if race conditions do give issues it will only mess up your data. Which might not be a big problem. If you know the Entity in the query is never looked up in the ComponentLookup it will be fine. It is (always) the most performant solution, since for the other two more work needs to be done before or after the Job.