- Home /
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)
{
}
}
Answer by Bunny83 · Oct 15, 2018 at 11:41 PM
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.
Answer by UnityCoach · Oct 13, 2018 at 09:15 PM
Make sure to assign its Collider a PhysicMaterial2D with full bounciness at 1 and that others also have a bounciness of 1.
Do not apply force from within Update, but from FixedUpdate.
Use ForceMode2D.Impulse to always give the same amount of force, ForceMode2D.Force (default) is weighted over Time.fixedDeltaTime.
Sorry for the delayed response. I implemented all of these suggestions, and there is no change. The result is still the same. Does it matter if it's in Update or FixedUpdate if it's just happening once (on the input command), rather than every frame/second?
Actually you have to have that code in Update and not in FixedUpdate. The input detection only works in Update. FixedUpdate only needs to be used when you have continuous forces.
Note that transform.up is not the world up direction but relative to your object. So if your ball can rotate it might point in any random direction.
Your answer
Follow this Question
Related Questions
Rigidbody2D doesn't move 0 Answers
Weird behaviour after Collision? 0 Answers
Child GameObject can't use MovePosition on parent's Rigidbody2D? 3 Answers
Move an object via Rigidbody2D Physics and Transform at same time 0 Answers
Simple moving ball script 1 Answer