Detecting on which side of the box a collision occurred

Explanation

I have a rectangle with a trigger on it when it's hit by my player game object from the side it's supposed to activate a certain method. Illustration:

And when it's hit from the bottom or top it's supposed to activate an other method. Illustration:

However the way I'm checking what method to use is not working in all cases.

Problem

There are some cases where the player is hitting the side of the rectangle but the method being called is the one supposed to be called when the rectangle is hit from the bottom or the top. When the player is hitting the top or bottom everything is working just fine.

Code

protected override void OnCollision(Collider2D coll, PlayerMovement player)
{
float playerMaxY = player.YCord + player.Height / 2;
float playerMinY = player.YCord - player.Height / 2;

//YCord is the y coordinate of the rectangle
float thisMaxY = YCord + Height / 2;
float thisMinY = YCord - Height / 2;

base.OnCollision(coll, player);

//This condition here is where i need an improvement
if ((playerMinY >= thisMaxY && playerMaxY >= thisMaxY) ||
(playerMinY >= thisMinY && playerMaxY >= thisMinY))
BounceHorizontal(coll, player);
else
BounceVertical(coll, player);
}

• Use raycasts. Or don't do it this way, you can use physics material to set bounciness. Or you could just take different approach and make your object bounce opposite direction from hit point world position. Or you could make the same with opposite direction but clamp the values of direction vector to match vertical or horizontal direction - you can achieve this with dot product on a normalized vector with (1, 0) (1, 1) (0, 1) (0, 0) - pick the one with the higher value - max is 1 if vectors lie on each other. – Candid Moon _Max_ Jan 30 '18 at 20:42

In case you do need collisions from bot, consider the following graphic:

In these two cases you have a vertical collision. In all the other ones, you have a horizontal one. So you get:

if ((playerMinY >= thisMaxY) ||
(playerMaxY <= thisMinY))
BounceVertical(coll, player);
else
BounceHorizontal(coll, player);


In case the corner of the player hits exactly the corner of the rectangle, it would bounce vertical.

• Thank you very much! I don't know how I got stuck on this part for so long. Now that I see the answer I feel really silly. – Filip G. Jan 31 '18 at 10:11
• @FilipG. Do not feel silly, sometimes the "easy" parts can be the most tricky ones ;-) . – Noctive Games Feb 2 '18 at 0:12

I'm going to break down this statement:

if ((playerMinY >= thisMaxY && playerMaxY >= thisMaxY) ||
(playerMinY >= thisMinY && playerMaxY >= thisMinY))


The first part says "if the bottom of the player is greater than the top of the platform and the top of the player is greater than the top of the platform."

• Hold on: why do we need this AND statement? The top of the player will always be greater than the bottom of the player and the bttom of the player is already known to be greater than the platform's maximum Y.

The second part says "if the bottom of the player is greater than the bottom of the platform and if the top of the player is greater than the top of the platform."

• Again, the second half is unneccessary: the top of the player will always be greater than the bottom of the platform if the bottom of the player is!

• Secondly...this logic will be true when the player collides with the side of the platform, but their feet are higher up than the platform is. As in precisely this case!

• Third...because these two statements have been ORed together, the second part will always be true any time the first one is: If the player's feet are above the top of the platform, they're clearly above the bottom of it too!

Yikes! Your code isn't distinguishing these two cases at all!

The only statement you can make that would result in your desired outcome is this:

if(playerMinY < thisMaxY)


The player's feet should never ever be below the top of the platform...unless they've collided with the sides (or bottom, but you haven't asked about collisions from below). Precisely the distinguishing factor you're looking for.

• Thanks for taking the time to go through the code and pointing out everything it does in great detail. It's now very clear to me where everything went wrong. AHHHHHHHHHHHHHHHHHHHHHHHHHH I feel so stupid haha – Filip G. Jan 31 '18 at 10:08