Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question 2D Get contact time and collider position when multiple collision in 1 physics fram

Discussion in 'Physics' started by Luwyliscious, Feb 3, 2023.

  1. Luwyliscious


    Mar 21, 2021
    When multiple contacts happen during 1 physics frame, the continuous detection collision solver seems to be able to detect all contacts, a "OnCollisionEnter2D" is triggered for every colliders and GetContacts retrieve the list of every contact that happened during the physics frame.

    The ContactPoint2D struct doesn't containt any time and the collider.transform / otherCollider.transform only contains the position of the colliders at the end of the physics frame. It seems impossible to get the positions and time that the Box2D collision solver had to calculate in order to properly calculate the result of the physics frame.

    I'm trying to achieve the following :
    • Smoothly interpolate position of a fast moving object even when multiple collision happens in a frame
    • Be able to override the collision response of a collider while still using unity's Phyics2D system
    If you override the bounce (velocity/position) of a fast moving rigidbody2D in the OnCollisionEnter2D method, the colliding object will actually already have bounce at the velocity calculated by the physics engine. As a result, if you then modify the velocity, the resulting motion will not be as precise as if the desired velocity was applied exactly at the point of contact and at the moment of contact.

    The provided interpolation for rigidbody2D only interpolate between the last known and newly calculated position, ignoring any collision that would have happened during the physics frame.

    In order to achieve my goals, I tried to :
    1. Manually simulate using Physics2d.Simulate()
    2. Gather all collisions that happened during this physics frame using OnCollisionEnter2D()
    3. Order the collisions as best as I can and calculate the object's position at each contact based on previous velocity (I only considered circle for this approach)
    4. Detect the first collision for which I want to override the collision response (if any)
    5. Redo simulation up to that point
    6. Set the desired velocity to my rigidbody
    7. Conclude the simulation for the remaining time (Recursivly loop if many custom collision in 1 physics frame)
    Then I use the calculated contacts and object positions to feed an interpolation script.

    My current implementation sometimes fails to order the contacts and properly position the colliders at each collision since I only have the normal impulse and contact point to help me figure the rigidbody's trajectory.

    In my current implementation, the added precision in collision response does help with the feel and "fairness" of a prototype i'm working on,and the accurate interpolation makes the motions feel more believable, especially when timescale is reduced (slowmo), but i'm having a hard time making it 100% reliable.

    Before I continue down that rabbit hole, is there any known way to access the actual contact time / position of colliders at the point of contact that were calculated by the continuous collision solver when multiple collision happens in 1 physics frame?