More information on why triggers don't trigger on initial overlap?

I encountered an issue in a recent version of Unity, where it seemed that triggers were firing one frame later than expected. It seems the behavior for triggers is that the engine only fires the trigger event when two colliders overlap for two consecutive frames. On the initial frame, as one collider begins to overlap another, the trigger enter event does not fire.

I reported this to Unity, but was told it’s just the way PhysX works, and has worked for 6+ years (https://issuetracker.unity3d.com/issues/collisions-are-detected-one-frame-later-than-they-occur)

I was wondering if there was more information on this? I’m able to use other physics methods to test whether one collider overlaps another (in Unity, it’s Physics.OverlapSphere) and I get accurate results with this approach. So I was wondering why specifically with triggers the results are less accurate, and only fire when overlap persists across multiple frames? Since this has been the case for so long, I assume it’s not considered a “bug”, but it’s inconsistent with the behavior of other scene queries, and therefore I’m confused about the reasoning.

A PhysX frame involves the following basic stages:

Collision detection
Constraint solver
Integration

Collision detection generates the set of overlapping pairs and any contacts required by the solver. Trigger pairs just produce overlap events that are not processed by the solver.

The constraint solver takes the set of contacts and joints and applies impulses to adjust the rigid bodies’ velocities to enforce contact constraints and joints.

Integration takes the velocities output by the constraint solver and advances time by the specified time-step to produce the final pose for the bodies.

It is these poses that the application renders using, but collision detection occurred using the initial pose (prior to integration).

This is why it seems like you don’t get overlap events until the frame after the shapes are visibly overlapping. It is not a bug, but just an artefact of the specific stepping scheme used. The shapes were not overlapping until after integration and no collision detection with the new poses has been performed yet.

This is consistent with the results you would have received from any scene queries prior to calling fetchResults, unless you are setting kinematic targets and have enabled the flag that uses kinematic targets as poses in SQ (which unity may well have enabled by default - I know that unreal enables this flag).

There isn’t much you can do to get the overlaps from the trigger system sooner because triggers do not support CCD (continuous collision detection). You could use regular collision detection (generate contacts but disable collision response) to emulate triggers and enable speculative CCD. This would probably give you overlap events if the bodies were going to overlap. However, this may give you false positives, e.g. if the unconstrained velocity would have resulted in an overlap bit the resulting velocity from the solver did not result in the shapes becoming overlapped). This inconsistency may be worse than waiting a frame to get the report.

Thank you for the detailed response. That’s very informative, and it’s reassuring (at least) to know that this is the expected behavior. In most cases, in my project, getting triggers to fire on the exact overlap frame isn’t important, so I’ll continue to use standard triggers. For the one special case, where the initial overlap frame really matters, I’ve stopped using triggers, and instead I perform a manual overlap sphere test instead. So I’ll keep doing that, understanding now that this is probably the best option.

Thanks again.