Smooth bounce on collision enter

In 2D platformer I try to make smooth bounce on touching enemy and some cooldown, using OnCollisionEnter2D.

IEnumerator CooldownHandler()
    {
        damagedByCollision = true;
        yield return new WaitForSeconds(2f);
        damagedByCollision = false;
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (damagedByCollision == false)
        {
            StartCoroutine(CooldownHandler());

            if (collision.collider.tag == "Enemy")
            {
                Hurt(20);

                if (transform.position.x <= collision.collider.gameObject.transform.position.x)
                {
                    transform.position = new Vector3(transform.position.x - 7, transform.position.y + 1, 0);
                }
                else
                {
                    transform.position = new Vector3(transform.position.x + 7, transform.position.y + 1, 0);
                }
            }
        }
    }

That’s working, but bounce is not at all smooth, it’s rather a rude teleportation.
I was adviced to use rigidBody.AddForce, but it is not working with neither Force nor Impulse. No reaction. For example:

rb.AddForce(new Vector2(transform.position.x + 7, transform.position.y + 2));

How can I use it correctly or maybe there’s another solution?

Line 20 and 24 need to NOT set the position immediately but instead set it over a period of time, such as via a 'tweening operation.

ALSO: With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

1 Like

Thanks for reply. Did I understand correctly that the best way is using simple animation or DOTween (I’ve just found that tool)? Or what is 'tweening operation meant by?

I have no idea what a “best way” is, but I assure you that setting a transform will instantly move an object.

If a canned animation works for you, great, but since this is physics based and a platform, I imagine it might start from anyplace, so canned animation is probably not useful.

If tweening works, you can do that too, but if you have OTHER code simultaneously still driving this object, OR you leave the Rigidbody still going on it, then those two sources will fight over it.

Alternately you could set a timer and do the tweening yourself by driving the positions (see MovePosition()) over a short period of time to the desired location. To this end you may wish to look up tutorials for knockback, as that sounds like what you might be doing.

1 Like