Entity found by physics CalculateDistance does not exist

I have the following setup:

  • BeginInitializationCommandBuffer - Destroys killed entities

  • TargetingSystem - Finds targets in range and puts them in a buffer

  • GetComponentsFromEntityTestSystem - Checks if targets exist

  • Other Systems - Attack and (possibly) destroy targets via BeginInitializationCommandBuffer

The third step however does sometimes throw an “Entity Entity(XXX:XXX) does not exist” error.
As there are no active command buffers between the TargetingSystem and the GetComponentsFromEntityTestSystem, it seems like the collisionWorld.CalculateDistance returns entities that have already been destroyed.

Does this have anything to to with when the physics world is being built or updated?
I replaced the TargetingSystem with a system that does not use physics, which is obviously slower, but does not produce the same error.

public class PhysicsTargetingSystem : SystemBase
{
    private BuildPhysicsWorld buildPhysicsWorld;

    private EndFramePhysicsSystem endFramePhysicsSystem;

    protected override void OnCreate()
    {
        this.buildPhysicsWorld = World.GetExistingSystem<BuildPhysicsWorld>();
        this.endFramePhysicsSystem = World.GetExistingSystem<EndFramePhysicsSystem>();
    }

    protected override void OnUpdate()
    {
        var collisionWorld = this.buildPhysicsWorld.PhysicsWorld.CollisionWorld;
        this.Dependency =
            JobHandle.CombineDependencies(this.Dependency, this.endFramePhysicsSystem.GetOutputDependency());


        Entities.ForEach(
            (Entity entity, ref LocalToWorld trans, ref DynamicBuffer<Target> targets, in SphereTargeting sphereTargeting,
                in CollisionInput collInput) =>
            {
                var hits = new NativeList<DistanceHit>(Allocator.Temp);

                var filter = new CollisionFilter()
                {
                    BelongsTo = (uint) collInput.BelongsTo,
                    CollidesWith = (uint) collInput.CollidesWith,
                    GroupIndex = 0
                };

                var distanceInput = new PointDistanceInput()
                {
                    Position = trans.Position,
                    MaxDistance = sphereTargeting.Radius,
                    Filter = filter
                };

                collisionWorld.CalculateDistance(distanceInput, ref hits);

                targets.Clear();
                for (int i = 0; i < hits.Length; i++)
                {
                    if (entity == hits[i].Entity) continue; //Ignore self
                    targets.Add(new Target()
                    {
                        Entity = hits[i].Entity,
                    });
                }

                hits.Dispose();
            }).ScheduleParallel();
    }
}
public class GetComponentsFromEntityTestSystem : SystemBase
{
    protected override void OnUpdate()
    {
        var positions = GetComponentDataFromEntity<LocalToWorld>(true);

        Entities
            .WithReadOnly(positions)
            .ForEach((
                Entity entity,
                ref DynamicBuffer<Target> targets,
                in LocalToWorld localToWorld) =>
            {
                for (int i = 0; i < targets.Length; i++)
                {
                    if(!positions.HasComponent(targets[i].Entity)) Debug.LogError($"Entity {targets[i].Entity} does not exist");
                }
            }).ScheduleParallel();
    }
}

Found your post while troubleshooting same kind of problem with destroyed entities from other systems.

I ended up copying from examples from documentation, and these did the trick for me:

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    [UpdateAfter(typeof(StepPhysicsWorld))]
    [UpdateBefore(typeof(ExportPhysicsWorld))]

before your system, and add this,

        protected override void OnStartRunning()
        {
            this.RegisterPhysicsRuntimeSystemReadOnly();
        }