0
\$\begingroup\$

I am making a 2D game where balls bounce from the edges of the screen, However, there seem to be two types of issues with this kind of bounce method, and every tutorial I checked uses the same method. Even though these issues happen rarely in the game, I created the exact moment they happen, you can see both issues in the video. https://streamable.com/g6fj4u

  1. Sometimes, the objects do not recognize the collision between each other, and even if they do, they bounce in the wrong direction.
  2. When colliding with the corner, object loses momentum and moves alongside one of the edges

This is the code I am using;

private void Awake()
{
    _transform = transform;
    _rigidBody2D = GetComponent<Rigidbody2D>();

    _rigidBody2D.velocity = _moveDirection * _speed;
}

private void FixedUpdate()
{
    _previousVelocity = _rigidBody2D.velocity;
}

private void OnCollisionEnter2D(Collision2D collision)
{
    Vector2 normal = collision.GetContact(0).normal;
    Vector2 reflection = Vector2.Reflect(_previousVelocity, normal).normalized;

    _rigidBody2D.velocity = reflection * _speed;
}
\$\endgroup\$
3
  • \$\begingroup\$ One thing I notice is that you're not updating _previousVelocity after each collision. So if a ball has a double collision in a single physics tick (like colliding quickly with two walls as it strikes an inside corner) the first collision is semi-forgotten and the second reflects velocity as though the first didn't happen. \$\endgroup\$
    – DMGregory
    Commented Nov 14, 2023 at 13:05
  • \$\begingroup\$ Also, are you using discrete or continuous collision detection? \$\endgroup\$
    – DMGregory
    Commented Nov 14, 2023 at 13:38
  • \$\begingroup\$ Continuous, i tried updating the previousvel after the collision as well but it seems like it doesn't affect much. It appears the issues come from somewhere else. \$\endgroup\$
    – ZozeR
    Commented Nov 14, 2023 at 14:16

2 Answers 2

3
\$\begingroup\$

It appears that your code is fighting with the physics engine about who gets to control the velocity vectors of the balls.

When there is a collision between two rigidbodies, then the Unity physics engine will do the same thing you are doing here: Resolve the collision by calculating the new velocity vectors of the involved rigidbodies. By trying to take its job without telling it, you are confusing the physics engine.

Possible approaches to this problem are:

  • Don't try to handle collisions in code. Leave collision resolution completely to the physics engine. You can tweak the collision behavior by assigning a Physics Material 2D to the rigidbodies of the balls and the walls.
  • Don't let the physics engine handle the movement. Set the "Body Type" of the Rigidbody 2D components to "Kinematic", so the physics engine is no longer responsible for controlling their movement, and implement your own movement code in FixedUpdate.
\$\endgroup\$
1
\$\begingroup\$

These issues can be solved by calculating the average normal, instead of the first collision normal.

private void HandleCollision(Collision2D collision)
{
    int contactCount = collision.GetContacts(_contacts);
    Vector2 normal = Vector2.zero;

    for (var i = 0; i < contactCount; ++i)
    {
        Vector2 contactNormal = _contacts[i].normal;

        if (Vector2.Dot(_previousVelocity, contactNormal) > 0f)
            continue;

        normal += contactNormal;
    }

    if (normal == Vector2.zero)
        return;

    Vector2 reflection = Vector2.Reflect(_previousVelocity, normal).normalized;

    _rigidBody2D.velocity = reflection * _speed;
    _previousVelocity = _rigidBody2D.velocity;
}

There seems to be a third issue, where bounce collision does not share energy like it would in real life, this sometimes results in weird bounces when colliding with another moving object.

You can access the velocity of the collided object and take that into account while doing the calculation, however, for a simple bounce, this would be overkill. It is better to use the unity physics material instead.

We have discussed this topic in the Unity Forum, You can check it out from the link below.

https://forum.unity.com/threads/2d-bounce-has-issues-with-corners-collisions.1516451/#post-9470837

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .