Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug In netcode for entities the ITriggerEventJob keeps receiving collision events long after a colliding

Discussion in 'NetCode for ECS' started by te_headfirst, Dec 1, 2023.

  1. te_headfirst

    te_headfirst

    Joined:
    Aug 1, 2023
    Posts:
    18
    Hi there,

    I am experiencing some unexpected behaviour when using ITriggerEventJob for handling collisions in our ECS with netcode for entities based game.

    I created custom "CollisionDetectionSystem" to handle collissions. The system uses the ITriggerEventJob for this. When a collision is detected the "CollisionDetectionSystem" destroys the entity that collided with the other entity.

    From the debug console I can see that it does register the collision and that the destroy part works (of course with the latency from when the server destroys the entity until is recognized as no longer there, all expected in a network based game).

    But even though the entity no longer exists (state.EntityManager.Exists returns false) the ITriggerEventJob keeps on firing that a collision occurred between entities with same index and version but without any components.

    It has been programmed to run server side.

    Thus the trigger job keeps reporting a collision each frame between the destroyed entities until, and this is where it gets really strange, a new ball is instantiated.

    Please find attached project for reproducing the described behaviour. (Start the SampleScene and inspect the console frame by frame from when the ball hits the ground).

    Note that I also did a non-netcode for entities version (just plain ECS) and here the ITriggerEventJob worked as expected and does not continue to fire after the colliding entity is destroyed.

    It looks like some problem in the combination of "netcode for entities" and ITriggerEventJob, but could also be that I am doing something wrong with regards to Ghost configuration, system ordering, or other.

    DISCLAIMER: The attached project is created only to prove a point, it is not pretty code :)
     

    Attached Files:

    Last edited: Dec 1, 2023
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    The ITriggerEventJob IIRC uses the physics event stream that are cleanup every frame. In particular the

    `simulation.TriggerEvents` is what is used to iterate over the triggered events. So looks like something is not cleared correctly in between server updates for some reasons.
    The event stream are disposed by the Simulation.ScheduleReset method that is called every frame the physics runs.

    And this last point I think is the tricky bit. With netcode we run the physics loop only if there are ghosts with physics or if lag compensation is enabled (the latter can be a workaround). So, my guess is that if you destroy all ghosts, we don't run any physics system anymore, we don't cleanup the queues and thus, this is triggered all the time.
     
    te_headfirst likes this.
  3. te_headfirst

    te_headfirst

    Joined:
    Aug 1, 2023
    Posts:
    18
    Thank you for your reply. Your analysis is correct. I tried to add another entity with a RigidBody to the scene and now the ITriggerEventJob stops reporting collision when the colliding object is destroyed.

    I guess it should be very rare that no ghosts with ridigbodies exist in the scene, at least in our case. Never the less if not already there, it would be good with a small note on the ITriggerEventJob documentation stating what you said: "With netcode we run the physics loop only if there are ghosts with physics or if lag compensation is enabled".

    Thank you again for your prompt response :)
     
    Last edited: Dec 8, 2023