Search Instagram Twitter Facebook Spotify Grid Tag Date Folder Chat Pencil

Development Update – Trigger Probelm

I was dealing with a very weird bug yesterday that was very difficult to pin down. At its basis, the bug has to do with the way Unity handles collisions. It was incredibly frustrating trying to figure out what the exact problem was and I was nearly going crazy.

I think I’ve finally solved the issue… Here’s the write up explaining what the problem was and how I solved it.

Trigger Problem

Here’s the problem: I place the first blue box on the switch. On the switch, there is a trigger which detects the blue box and turns it on (signaled by the light). When I take the second blue box, and bump it against the first, somehow OnTriggerExit() is called, even those the first blue box hasn’t moved.

I should clarify it’s not the size of the trigger. Obviously if it was a big trigger, and the second box entered and exited, OnTriggerExit() would be called.

This is what the trigger looks like:

As you can see, it’s 0.25 x 0.25 in the center of the square, so the first blue box covers it completely.

Collision of Kinematic Rigidbody vs Non-Kinematic Rigidbody

As I started to dig into the issue, I realized again that Unity handles collision with kinematic and non-kinematic rigidbodies very differently. I say again because I actually noticed this back when I first started working on RELATIVITY (hence why all non-moving boxes are set to kinematic).

Here’s a gif demonstrating the difference. The green box is a non-kinematic rigidbody that has constraints on position and rotation (so that’s not moving), while the yellow box is a kinematic rigidbody. Look at how much the blue box penetrates the green box:

Box Set Up

With the above info in mind, I’m going to take a small detour and explain how the boxes are set up (this all comes together, I promise).

The boxes in the game are 1x1x1 box, with 6 plane detectors (known as “Bottom Collision Detectors” on the surface of each face.

Each box can belong to one of six gravity fields. Its gravity orientation depends on which gravity field it belongs to.

To get the box to “fall”, instead of using Unity’s default physics, I apply an acceleration force using ForceMode.Acceleartion in FixedUpdate() in the direction of the box’s gravity.

Only one Bottom Collision Detector is active, depending on which direction the box is falling. Namely, the detector at the bottom of the box. Its purpose is to let the box known when it has contacted something beneath it ie when it has landed.

I do this for a couple of reasons:

1) So the acceleration force doesn’t keep getting applied. I’ve had cases where the box got pushed past whatever was beneath it and fell through the floor.

2) So that the box knows to be set to kinematic, so that when the player pushes a box against it, it doesn’t penetrate.

So what was going on?

I started to look at the state of the rigidbody of the box, and realized what was happening was that it was becoming non-kinematic when the second box hit it.

And then I realized that this was happening because the second box was entering and exiting the Bottom Collision Detector, tricking it into thinking that box was not on the ground.

This allowed the second box to penetrate the first box, and that set off the trigger.

At least that is my diagnosis.

Solution

I decided to use OnCollisionEnter on the box to detect when something is below.

I get all the collision contact points, and if those points have a normal that is the inverse of the gravity direction, then something is below.

Also, I offset the detectors from the faces of the box slightly:

This way, the bottom collision detector is below the ground, so when another box penetrates the the box, it doesn’t hit the trigger.

This seems to fix the problem so far.

My code now is a mess from debugging, so I’m going to clean up the code and try to see if there are any more edge cases in which the system breaks down.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.