In Unity Physics2D, It’s able to get contact points in OnCollisionEnter2D().
public void OnCollisionEnter2D(Collision2D collision)
{
var contacts = collision.contacts;
foreach (var contact in contacts)
{
print(contact.point);
}
}
But the contact points is in world space, not the positions of the Rigidbody2Ds.
Someone may say, a point in world space can be converted to local space by Transform.InverseTransformPoint()
, and that is the position of the Rigidbody2D.
But After some experiments, I found that only using Transform.InverseTransformPoint()
would not get the precise position.
Let me explain.
In Unity’s Order of execution for event functions, FixedUpdate, Internal Physics Update, OnCollisionEnter2D happens in order.
Assume there are 2 small boxes, both have bounceness = 1. So after collision they will go apart.
In FixedUpdate, they are coming near.
In Internal Physics Update, they collide with each and then go apart. The contact pointis the real position they collider in world space.
In OnCollisionEnter2D, they are no longer at the collision position, but at the position some distance apart from the collision position. So if I calculated the position by
Transform.InverseTransformPoint()
here, I would get a wrong answer.Example above neglects anglar velocity, if there are non-zero anglar velocities, things will be more complicated.
So, how to get the contact points of the Rigidbody2Ds?