'Weird ContactPoint2D on two BoxCollider2D collision

Well, while creating a kind of 2D platformer using Tilemaps for creating levels consisting of blocks I stumbled upon a problem with weird contact points I get on collision between my player's BoxCollider2D and TilemapCollider2D. I need to detect what tiles specifically the incoming collider is colliding with and because of this problem I often gain wrong tiles positions. Then I discovered that the very same problem of detecting contact points is actual for the collision of two BoxCollider2D so here is the test with them.

The last frame before the collision was detected. BoxCollider of a cube is perfectly aligned to the grid. Player's falling on collider from above (Collision Detection mode is Discrete).

The next frame. Player's collider changed it's position trying to get out of collider what is OK. Red dots are bottom corners of the collider from the previous frame and white dots are contact points returned at this frame from Collision2D.GetContacts(). We get two points, but the left one is out of collider bounds. I expected (and it seems quite logical) that all the points must be inside the colliders intersection area.

Here is the script attached to the Square that gets contacts and places dots in them:

public class Test : MonoBehaviour
{
    [SerializeField] private BoxCollider2D _collider;
    [SerializeField] private GameObject _contactDotWhite;

    private ContactPoint2D[] _contacts = new ContactPoint2D[5];
    
    private void OnCollisionEnter2D(Collision2D other)
    {
        other.GetContacts(_contacts);
        for (var i = 0; i < other.contactCount; i++)
        {
            ContactPoint2D contact = _contacts[i];
            GameObject go = Instantiate(_contactDotWhite);
            go.transform.position = contact.point;
        }
    }
}

So, the questions are: how unity calculates these contact points? Is this a normal behaviour at all? If it's not, how do I fix it?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source