How Do I Make a Rigidbody2d keep its force and move at a consistent speed?

I’m making a Breakout-like. I’m using rigidbody2d.addforce to move the ball, but it will lose all its force and start moving extremely slowly any time it hits a dynamic rigidbody2d, and in some other instances where it hits an object at an unusual angle. Is there anyway to stop this? I just want the ball to move at a single, consistent speed no matter what it hits. Ball script attached for reference.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ball : MonoBehaviour
{
    Rigidbody2D rb;
    //Variable for rigidbody

    bool gameActive;
    //Variable for whether or not the ball is in play

    public float ballForce;
    //Variable for how much force is added to ball (determines speed)

	void Start()
    {
        rb = GetComponent <Rigidbody2D>();
        //Assigns ball's rigidbody to rigidbody variable

        gameActive = false;
        //Confirms that ball is not yet in play
    }
	
	void Update()
    {
        if (Input.GetButtonDown("Launch") && gameActive == false)
        //If player presses launch button when ball is not active
        {
            transform.SetParent(null);
            //Unparents ball from paddle

            rb.isKinematic = false;
            //Activates ball's rigidbody

            rb.AddForce(transform.up * ballForce);
            //Adds upward force to ball at start according to ballForce variable

            gameActive = true;
            //Confirms that ball is now in play, so launch function can't be activated again
        }
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {

    }
}

Well breakout doesn’t really use physics. Because when a moving object hit another moving object the speed may increase (if moving into each other) or decrease (if moving in the same direction). Since you don’t want that you shouldn’t actually rely on that. There are several ways how you could solve this.

First would be to simply ensure a constant velocity. This can be done by adding this line in FixedUpdate;

rb.velocity = rb.velocity.normalized * speed;

This will ensure the velocity is always “speed”. So even when a collision changes the magnitude and direction of the velocity, the magnitude will be forced to a length of “speed”.

Another solution would be to do the reflecting manually. Usually you would use raycasts to check where the ball hits and use the surface normal to calculate the reflected direction. Which one is better depends on your needs. The simplest solution is the first one.

  1. Make sure to assign its Collider a PhysicMaterial2D with full bounciness at 1 and that others also have a bounciness of 1.
  2. Do not apply force from within Update, but from FixedUpdate.
  3. Use ForceMode2D.Impulse to always give the same amount of force, ForceMode2D.Force (default) is weighted over Time.fixedDeltaTime.