# detect side of collision in box collider 2d?

I’m new to unity3d. I have seen this question has been asked in many places but I couldn’t figure out how to solve this problem. I have two objects with box collider 2d target and a ball with Circle Collider 2d. I want to detect the side of target box when ball hits the target.
simply my question is how to detect the side ball hits in the box(top,left,bottom or right). I could get the the position of the hitting object with following code but it’s useless.

``````void OnCollisionEnter2D(Collision2D  collision)
{
Collider2D collider = collision.collider;

if(collider.name== "target")
{
print(collider.name);

ContactPoint2D contact = collision.contacts;
Vector3 pos = contact.point;

print(pos);
}
}
``````

Use collider.bounds.center and compare it with the point.

``````void OnCollisionEnter2D(Collision2D  collision)
{
Collider2D collider = collision.collider;

if(collider.name == "target")
{
Vector3 contactPoint = collision.contacts.point;
Vector3 center = collider.bounds.center;

bool right = contactPoint.x > center.x;
bool top = contactPoint.y > center.y;
}
}
``````

This is going to be a little basic of me, but please forgive my ignorance, can anyone explain a bit as to why this works? or point me to a resource where I can read more about it. i’m a little confused.

For the curious, I solved this problem using the following code

``````    private string WhatSideOfTheColliderWasHit(Collider2D collision)
{
Vector2 PointOnBoxHit = collision.ClosestPoint(transform.position);
Vector2 centerOfObject = collision.bounds.center;
float xMinPoint = Mathf.Abs((collision.bounds.size.x/2) - centerOfObject.x);
float xMaxPoint = Mathf.Abs(xMinPoint + collision.bounds.size.x);
float yMinPoint = Mathf.Abs((collision.bounds.size.y / 2) - centerOfObject.y);
float yMaxPoint = Mathf.Abs(yMinPoint + collision.bounds.size.y);

if (PointOnBoxHit.x >= xMinPoint && PointOnBoxHit.x <= xMaxPoint && Approximately(yMaxPoint, PointOnBoxHit.y, .1f))
return "Bottom";
else if (PointOnBoxHit.x >= xMinPoint && PointOnBoxHit.x <= xMaxPoint && Approximately(yMinPoint, PointOnBoxHit.y, .1f))
return "Top";
else if (PointOnBoxHit.y >= yMinPoint && PointOnBoxHit.y <= yMaxPoint && Approximately(xMaxPoint, PointOnBoxHit.y, .1f))
return "Right";
else
return "Left";
}
``````

The basic idea is that I grab the closest point on the collider box where the collision happened. I then get the calculate the min/max of x and y of this particular box. I then simply compare my point to these min/max values. It tells exactly what side of the box I am on.

Also Approximately is my own function that basically checks to see if the two values are within a threshold. It’s like Mathf.Approximately but I can control the epsilon.

Edit: You may have a problem with certain blocks returning size = 0,0,0 in some cases. If this happens then just go after size from the component

``````Vector3 size = collision.gameObject.GetComponent<BoxCollider2D>().size;
``````

That fixed the issue for me. Then for the code above that calls for size, just replace collision.bounds.size with just size.

Here is a easier way to make that:

• Get the collision point by ClosestPoint
(Unity - Scripting API: Collider2D.ClosestPoint)
• Get the distance from collision object center (using bounds.center) to closestPoint
• Get the angle of the distance
• Draw a box somewhere and trace lines to determine wich part of the box will make a different action.
• Create a enum for each one of them.
• Check the angles and return the enum.

Here is the code:

``````private static CollisionSide CheckIfFloorIsUnder(Collider2D thisCollider, Collider2D otherCollider)
{
var closestPoint = otherCollider.ClosestPoint(thisCollider.bounds.center);
var distance = closestPoint - (Vector2)otherCollider.bounds.center;
var angle = Vector2.Angle(Vector2.right, distance);
if (angle < 135 && angle > 45)
{
return CollisionSide.Under;
}
//The rest of sides by angle
return CollisionSide.None;
}

public enum CollisionSide
{
Under,
Above,
Sides,
None,
}
``````