ECS follow entity

I was playing around with the new entity component system and I came across a problem I was not able to solve.
I try to make an entity follow another entity. I want to do it in a job and not on the main thread.
I already wrote some code in order to accomplish that:

FollowEntityComponent.cs

using Unity.Entities;
using Unity.Mathematics;

public struct FollowEntityComponent : IComponentData
{
    public Entity entityToFollow;
    public float3 offset;
}

FollowEntitySystem.cs

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Jobs;
using Unity.Burst;
using Unity.Collections;

public class FollowEntitySystem : JobComponentSystem
{
    struct FollowEntityJob : IJobForEach<Translation, FollowEntityComponent>
    {
        [ReadOnly] public ComponentDataFromEntity<Translation> translationComponentFromEntityToFollow;

        public void Execute(ref Translation translationComponent, ref FollowEntityComponent followEntityComponent)
        {
            if (!translationComponentFromEntityToFollow.Exists(followEntityComponent.entityToFollow))
            {
                return;
            }
            float3 entityToFollowPosition = translationComponentFromEntityToFollow[followEntityComponent.entityToFollow].Value;
            translationComponent.Value = entityToFollowPosition + followEntityComponent.offset;
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        FollowEntityJob followEntityJob = new FollowEntityJob()
        {
            translationComponentFromEntityToFollow = GetComponentDataFromEntity<Translation>(true)
        };
        return followEntityJob.Schedule(this, inputDeps);
    }
}

The code does actually compile, however, I get the following error when I hit play:

InvalidOperationException: The writable NativeArray FollowEntityJob.Iterator is the same NativeArray as FollowEntityJob.Data.translationComponentFromEntityToFollow, two NativeArrays may not be the same (aliasing).

I already figured out why I am getting this error message. It is because I am having a Translation component in IJobForEach<Translation, FollowEntityComponent> and in [ReadOnly] public ComponentDataFromEntity<Translation> translationComponentFromEntityToFollow; this seems to cause the error. (See: Options for Entity interaction - Unite Copenhagen - YouTube , minute: 21:53).
However, even when I know the reason I can not figure out a better way of accomplishing what I want to do. I would be very thankful if somebody could provide me a solution to my problem.

Hello @FelixKahle ,

not sure if you already figured it out, but I found a solution:
The problem is, as @Igarczyn already stated, the aliasation. However, you can avoid that by not depending on the Translation component, but the LocalToWorld component instead.

So you can adjust your code like this:

public class FollowEntitySystem : JobComponentSystem
 {
     struct FollowEntityJob : IJobForEach<Translation, FollowEntityComponent>
     {
         [ReadOnly] public ComponentDataFromEntity<LocalToWorld> localToWorldFromEntityToFollow;
 
         public void Execute(ref Translation translationComponent, ref FollowEntityComponent followEntityComponent)
         {
             if (!localToWorldFromEntityToFollow.Exists(followEntityComponent.entityToFollow))
             {
                 return;
             }
             float3 entityToFollowPosition = localToWorldFromEntityToFollow[followEntityComponent.entityToFollow].Position;
             translationComponent.Value = entityToFollowPosition + followEntityComponent.offset;
         }
     }
 
     protected override JobHandle OnUpdate(JobHandle inputDeps)
     {
         FollowEntityJob followEntityJob = new FollowEntityJob()
         {
             localToWorldFromEntityToFollow = GetComponentDataFromEntity<LocalToWorld>(true)
         };
         return followEntityJob.Schedule(this, inputDeps);
     }
 }

The problem is not in this code, you are passing overlapping pointers (in that case likely the same array) to both arguments of the function to run your entities.

Passing the same array (aliazation error) is likely an error, but also extremely dangerous for a number of reasons regarding optimization and memory safety.

But how would you overcome the problem that you have to read the position (translation) of the entity to follow as well as write to the position (translation as well) from the entity, which should follow the other one. I cant figure out how I should design a solution for that problem.