How does Unity compensate for the force entering the collider so beautifully?

Hi,
I need point physics that forms a polygon collider, since this is not built into Unity, I wrote my own, but my collision physics is ugly:

void VelocityChanges(Vector3 directionNormalFromCollisionPointNormalized,
    Rigidbody2D rbPoint1,
    Rigidbody2D rbPoint2)
{
    //=========================================================== Detect forces
    float forceRb = Vector2.Dot(rb.velocity, -directionNormalFromCollisionPointNormalized);
    float forceRbPoint1 = 0;
    float forceRbPoint2 = 0;
    if (rbPoint1 != null)
    {
        forceRbPoint1 = Vector2.Dot(rbPoint1.velocity, directionNormalFromCollisionPointNormalized);
        forceRbPoint2 = Vector2.Dot(rbPoint2.velocity, directionNormalFromCollisionPointNormalized);
    }
    //=========================================================== Detect forces
    //=========================================================== Calculate forces
    CheckNegetiveDirectionAndAddForce(rb, directionNormalFromCollisionPointNormalized, forceRb, forceRbPoint2, forceRbPoint1);
    if (rbPoint1 != null)
    {
        CheckNegetiveDirectionAndAddForce(rbPoint1, -directionNormalFromCollisionPointNormalized, forceRbPoint1, forceRb/2f, 0);
        CheckNegetiveDirectionAndAddForce(rbPoint2, -directionNormalFromCollisionPointNormalized, forceRbPoint2, forceRb/2f, 0);
    }
    //=========================================================== Calculate forces
}


void CheckNegetiveDirectionAndAddForce(Rigidbody2D rb_,
    Vector2 direction, float abserbedForce,
    float force2, float force3)
{
    if (abserbedForce < 0) { abserbedForce = 0; }
    if (force2 < 0) { force2 = 0; }
    if (force3 < 0) { force3 = 0; }
    rb_.AddForce((abserbedForce + force2 + force3) * direction, ForceMode2D.Impulse);
}

What is the problem: when colliding, I determine the point of contact with another collider and move it there, this works fine, but then I need to apply forces and for example gravity constantly acts on the point it enters the collider and then is pushed out of it. The result is that the point constantly trembles (wobbles, shakes).

It is because of springs between the points, but I don’t understand how to fix it.

Unity in its rigidbody2d collisions makes it so that the force does not affect the collider at all, if the object is already on the surface of the collider, I want this for myself

I’d be grateful for any ideas

There’s not a trivial answer but the source code is here: GitHub - erincatto/box2d: Box2D is a 2D physics engine for games

1 Like

Thanks, collision.md does a great job of explaining collision behavior as in Unity. But that means I have a problem with the behavior of the springs, which press the object back into the wall immediately after the point has left the wall, I think this solution is correct: turn off the springs of the point that recently left the collider, and after the first processing of the movement of the springs, turn them on again for this point … although it may break the structure of the object

The 2D physics solver is an impulse-based contact solver. The joint (constraint) solver is the same thing but that’s about satisfying joint constraints not contact constraints. They are solved together. The subject, especially stability details gets quite complex quickly though.

Without understanding what your custom solution is here it’s hard to really help TBH.

For instance, I have no idea what “point physics” means. If you mean soft-body then you can easily do that too with stock 2D physics (depending on the scale) but there are other techniques such as verlet physics for instance.

My object system: the softbody consists of points (without a radius) and between the points there are three springs at each point, they form an elastic system. Between all points (vertices) each frame a PolygonCollider2D and MeshRenderer are drawn. Each point has Rigidbody2D. PolygonCollider2D (on object) - isTrigger for own calculations.

That sounds like a super expensive way of doing this. For starters, a PolygonCollider2D isn’t a dynamic thing; it has to decompose the outline into multiple physics shapes which isn’t cheap.

If you need a “point” to check for contacts then why not add a single CircleCollider2D with a tiny (minimal) radius. That way, it’s handled for you. You could even set that Rigidbody2D to be Continuous Collision Detection.

You could also make these Kinematic to remove their collision response but still get contacts points which you can solve or use something like Physics2D.Distance to calculate the separation/overlap for you.

About optimization: this is the only key mechanic in the game and there are not very many such objects, so far I see 60 fps with 30 objects on mobile.

About small circles: I tried to do this, but if the space between the points stretches, and it 100% stretches enormously, then a ball will fly in there, which will twist many times in the jungle of other balls.

Essentially I’m working on this mechanic:

another stupid idea of mine( it did nothing

https://www.youtube.com/watch?v=rty2bRiR95A

Does anyone know how to properly handle collisions of objects that consist of springs?
help, please

You don’t need to “handle them”. In the end, the solver is solving this so if you’re using lots of chained/dependent joints then I presume you’re not simply using the defaults for the solver? There’s solver iteration settings in the project settings which you can increase which allows the solver more iterations to produce a good solution.

Also, the joints are likely fine, I see you’re using Discrete collision detection which means you can get overlaps on contacts. Using continuous would solve that but is more expensive to solve. This is more important when you’re slamming things around like that i.e., forces/velocities are high.

What you’re doing here is nothing new, it’s been done lots of times without issue.

1 Like

big truth, I made a very big mistake with the intersection formula, your is better, thanks

1 Like