Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Entity found by physics CalculateDistance does not exist

Discussion in 'Entity Component System' started by peaj_metric, Feb 23, 2021.

  1. peaj_metric

    peaj_metric

    Joined:
    Sep 15, 2014
    Posts:
    145
    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.

    Code (CSharp):
    1. public class PhysicsTargetingSystem : SystemBase
    2. {
    3.     private BuildPhysicsWorld buildPhysicsWorld;
    4.  
    5.     private EndFramePhysicsSystem endFramePhysicsSystem;
    6.  
    7.     protected override void OnCreate()
    8.     {
    9.         this.buildPhysicsWorld = World.GetExistingSystem<BuildPhysicsWorld>();
    10.         this.endFramePhysicsSystem = World.GetExistingSystem<EndFramePhysicsSystem>();
    11.     }
    12.  
    13.     protected override void OnUpdate()
    14.     {
    15.         var collisionWorld = this.buildPhysicsWorld.PhysicsWorld.CollisionWorld;
    16.         this.Dependency =
    17.             JobHandle.CombineDependencies(this.Dependency, this.endFramePhysicsSystem.GetOutputDependency());
    18.  
    19.  
    20.         Entities.ForEach(
    21.             (Entity entity, ref LocalToWorld trans, ref DynamicBuffer<Target> targets, in SphereTargeting sphereTargeting,
    22.                 in CollisionInput collInput) =>
    23.             {
    24.                 var hits = new NativeList<DistanceHit>(Allocator.Temp);
    25.  
    26.                 var filter = new CollisionFilter()
    27.                 {
    28.                     BelongsTo = (uint) collInput.BelongsTo,
    29.                     CollidesWith = (uint) collInput.CollidesWith,
    30.                     GroupIndex = 0
    31.                 };
    32.  
    33.                 var distanceInput = new PointDistanceInput()
    34.                 {
    35.                     Position = trans.Position,
    36.                     MaxDistance = sphereTargeting.Radius,
    37.                     Filter = filter
    38.                 };
    39.  
    40.                 collisionWorld.CalculateDistance(distanceInput, ref hits);
    41.  
    42.                 targets.Clear();
    43.                 for (int i = 0; i < hits.Length; i++)
    44.                 {
    45.                     if (entity == hits[i].Entity) continue; //Ignore self
    46.                     targets.Add(new Target()
    47.                     {
    48.                         Entity = hits[i].Entity,
    49.                     });
    50.                 }
    51.  
    52.                 hits.Dispose();
    53.             }).ScheduleParallel();
    54.     }
    55. }
    Code (CSharp):
    1. public class GetComponentsFromEntityTestSystem : SystemBase
    2. {
    3.     protected override void OnUpdate()
    4.     {
    5.         var positions = GetComponentDataFromEntity<LocalToWorld>(true);
    6.  
    7.         Entities
    8.             .WithReadOnly(positions)
    9.             .ForEach((
    10.                 Entity entity,
    11.                 ref DynamicBuffer<Target> targets,
    12.                 in LocalToWorld localToWorld) =>
    13.             {
    14.                 for (int i = 0; i < targets.Length; i++)
    15.                 {
    16.                     if(!positions.HasComponent(targets[i].Entity)) Debug.LogError($"Entity {targets[i].Entity} does not exist");
    17.                 }
    18.             }).ScheduleParallel();
    19.     }
    20. }
     
  2. vildauget

    vildauget

    Joined:
    Mar 10, 2014
    Posts:
    120
    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:

    Code (CSharp):
    1. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    2.     [UpdateAfter(typeof(StepPhysicsWorld))]
    3.     [UpdateBefore(typeof(ExportPhysicsWorld))]
    before your system, and add this,

    Code (CSharp):
    1.         protected override void OnStartRunning()
    2.         {
    3.             this.RegisterPhysicsRuntimeSystemReadOnly();
    4.         }