[Not Resolved but Explained] OnTrigger* / OnCollision* Discrete collisions issue

Hello All,

I’ve been trying to understand a situation I’m seeing where I have a collision between 2 objects that have a box Collider on each and a RigidBody on each.

My issue is that my OnTriggerEnter function is not being called until the moving box (bomb - Marked as OnTrigger) has passed through the non-moving box (player).
In example terms take the following:

| P | <— | B |

I expect the OnTriggerEnter to hit when the following situations arises

| P|| B |

But instead I see it only when the objects are positioned as such:

| B ||P |

To check that this is the case I added to the FixedUpdate() call of the bomb a simple line to store the X value of the transform.position. This value is then printed out during the OnTriggerEnter function, along with the position of the bomb and position of the player.

I am seeing results similar to the following on all tests.

Player Box Collider size (4,4,4)
Bomb Box Collider size (6,6,6)

**Initial Values:**
Player Position = 1
Bomb Position   = 72
Bomb Force      = -500

Force added to the bomb is done using AddForce(). My Unity Physics timestep has been set to 0.01, every 10 ms, as this coincides with the physics checks on the game I am trying to recreate. I thus expect per FixedUpdate physics check, that this will move the bomb by 5 pixels per tick.

**Contact Point Values:**
Player Position = 1
Bomb Position   = -3.00001
LastX Value     = 1.99999 

Based on Bomb position and LastX I see a movement of 5 pixels, so that seems to work.

My issue is that the Radius of the player Collider is 2, and bomb is 3 and thus I would have expected the OnTriggerEnter event to fire when the bomb was at position X=2, not X=-3.
At X=2 there is definite overlap (entry) between the box colliders as the bomb would be extending it’s range from X=-1 to X=5, and the player box collider would extend from -1 to 3.

Can any of you explain what I am seeing and hopefully where I could be going wrong?
I’ve searched everywhere for detailed descriptions of Unity physics execution / checking with regards to collider overlap, and nothing has been able to explain my findings.

In the end my need is to calculate the exact pixel distance between the center of the bomb and center of the player, which works, except the distance is different than I expect as the collision is not registered before the bomb has passed through the player.


EDIT UPDATE (2015-04-20):

I’m starting to wonder if it’s my understanding of the various values that’s at fault here, as I’m running into this in another situation. Bombs hitting a wall.

The following data is from my exact test case I’m debugging right now:

*Bomb Details:*
rigidbody.position          = (-80.0, 2594.3, 0)
previous rigidbody.position = (-77.8, 2594.4, 0)  [saved in fixedUpdate()]
boxCollider.bounds.extents  = (2.5, 2.5, 2.5)
rigidbody.velocity          = (-225.0, -2.3, 0)
rigidbody.magnitude         = 2.250117
isTrigger                   = true
collision method            = discrete

*Wall Details*
rigidbody.position          = (-88.0, 2
boxCollider.bounds.extents  = (8.0, 8.0, 8.0)
isTrigger                   = false

This time I’m trying to cast Rays from my bomb’s corners in the direction of the rigidbody velocity, with a length equal to the velocity.magnitude * Time.fixedDeltaTime, to detect the collision surface, and thus adjust the bomb to bounce (position and velocity change).

However, as the leading edge (left edge in this case) is already inside the collider of the wall, it is not detecting a collision when I throw the 2.250117 length ray to the left (direction of travel).

Yes I know I could adjust the rays to come from the back wall of the bomb to work-around this issue, however, WHY is it working like this?

What I don’t understand is why in Discrete collisions (once per fixedUpdate), why am I not getting the onTriggerEnter when the rigidbody.position is at the previous value (-77.8)??? To me this would make sense as -77.8 - 2.5 = -80.3. The Collider on the Wall extends to -80 (-88 + 8). So why???

Is this a Unity collisions bug or is it due to the order of operations in Unity (FixedUpdate, OnTriggerEnter)???

Any help is appreciated as this is seriously affecting my understanding of Unity Physics at the low level and causing me to come to a standstill in the project. I can try ‘account’ for this situation, but I have a number of other areas still to go and need to understand why this is happening to handle them.

Finally decided it was time to raise a Unity Bug report.

http://issuetracker.unity3d.com/issues/ontriggerenter-not-firing-when-colliders-first-enter-each-other

Unity support was very quick in responding and has been helpful in providing back details through numerous correspondences. They pointed me to another issue that had been raised in the past with the exact same scenario documented:

Unfortunately that one is marked as “Won’t Fix”.

The issue appears to be with the order of operations that is performed during a PhysX step. As I was informed by support it is as follows:

*"the phases in PhysX are as follows

  1. Detect collisions and trigger overlaps.
  2. Move objects (simulation step)
  3. Report collision and trigger events from step 1, from before the move update."*

This is why I am seeing the objects has having moved one extra position when the OnTriggerEnter is fired. Unfortunately this means the information in the GameObject that has the Event code fired, will not be the same information as it was at the time of the collision. This also applies to the passed “Collider” information passed to the event function.

This could potentially mean the velocity information at the time of the collision is also incorrect, if either object had been under acceleration as the velocity would have been updated in the simulation step.

Hopefully the unity documentation for the OnTrigger* / OnCollision* and/or Discrete collisions, will be updated to explain this detail and prevent others wasting weeks like I did thinking I had screwed up somehow. :frowning:

More importantly, here’s hoping that PhysX will actually solve this issue at some point in the future by firing the Collision and Trigger events prior to performing the next simulation step.