OnSyncedTriggerEnter Triggering with "Ghost" Clones

Hi there! I noticed some strange behavior concerning OnSyncedTriggerEnter and object instantiation. I have a Unit object that instantiates when I press a button. The unit uses OnSyncedTriggerEnter to detect other Unit objects it may run into. I log Unit instance IDs during OnSyncedStart and OnSyncedTriggerEnter. On the home client (during a 1 v 1 match), the Unit instantiates as expected, logging Unit start and no trigger entry. On the peer client, something strange happens. I obtain something like this in the log:

Started UnitBehavior Script for a unit (ID = -13090) owned by Player 1
Started UnitBehavior Script for a unit (ID = -13120) owned by Player 1
Unit: Collision Trigger Entered between Unit(Clone):-13090 and Unit(Clone):-13128
Unit: Collision Trigger Entered between Unit(Clone):-13120 and Unit(Clone):-13098
Started UnitBehavior Script for a unit (ID = -13146) owned by Player 1
Unit: Collision Trigger Entered between Unit(Clone):-13120 and Unit(Clone):-13154
Unit: Collision Trigger Entered between Unit(Clone):-13146 and Unit(Clone):-13128
Unit: Collision Trigger Entered between Unit(Clone):-13090 and Unit(Clone):-13154
Unit: Collision Trigger Entered between Unit(Clone):-13146 and Unit(Clone):-13098

...where it seems like there is an initial Unit (bold) and other Units where OnSynced methods are called, and other Units (italics), "Ghost Clones," where OnSynced methods are not called. These triggers all happen in an instant and only "one" Unit is created and observed in the game screen.

This behavior is easily worked around by making sure OnSyncedTriggerEnter action isn't functional immediately upon instantiation (a "summoning delay" for example, in the context of a game). However, for someone who might want a new object to instantly use these triggers, say for example to immediately attack another Unit in vicinity, there may be some strange behavior. Is the observed behavior here what is expected? Let me know, thank you!

Comments

  • Hello @Mukikaizoku, thanks for your report, this will happen if you have rollbacks (rollback window greater than zero on TrueSyncConfig asset). We call the triggers on a "safe" tick and on a "rollback" tick, we are still going to add some bool or different callback if you want to use a safe callback for Trigger/Collision events.
  • Thank you for the response @JeffersonHenrique ! Indeed, when turning off the rollback, the collisions with these "ghosts" do not happen. Would you be able to clarify what is going on under the hood with the rollback that causes the triggers? Do you mean to say that the triggers are called even if there is no collision event? Let's say the SyncedInstantiate occurs on tick 5. The peer simulates tick 5 and creates the Unit #1. At tick 7, the peer decides it needs to rollback to tick 5. When rewound to tick 5, Unit #1 from before is present and then a new Unit #2 is added (triggers called for both), and then the instantiation for the Unit is confirmed correct so Unit #2 is discarded?
  • Exactly @Mukikaizoku, simulation runs and calls the callbacks as you said, rollback is needed to keep states synced between the clients.