- Home /
Keep constant velocity
Hi, I'm one of the many Unity newbies who's making a Breakout-ish game for learning purposes. I use physics for moving the ball and have physics materials with 1 bounciness and 0 friction on all the objects. Problem is that sometimes the ball looses its velocity. This usually happens when the ball gets squeezed between the paddle and the wall or in between two close bricks.
Have I overlooked anything or is there a way to force the ball to have a constant velocity? Best of all would be to have a script variable that allows me to increase or decrease the speed in-game.
I've looked into scripting the movement instead of using physics, but the math is way beyond my understanding :)
Answer by SilverTabby · Sep 25, 2011 at 09:32 PM
There are two ways to maintain a constant velocity on an object (that are easy that I know about)
If you are using a rigidbody, then inside of LateUpdate and/or Update simply set
rigidbody.velocity = constantVelocity;
If you are not using a rigidbody, or if you want there to be no way to interact with the object via physics, then simply do this in LateUpdate or Update:
transform.position += constantVelocity * Time.deltaTime;
where constantVelocity
is a Vector3 containing the desired change in position per second
Oh that's what you are looking for.
If you want constant speed, but non-constant direction then all you have to do is this:
rigidbody.velocity = constantSpeed * (rigidbody.velocity.normalized);
It maintains the current direction of the rigidbody, but will always scale the velocity vector to be of the correct speed.
note: - Speed is the rate something moves at. It is a float. - Direction is which way it is moving. It is a vector. - Velocity is both the direction and rate that something is moving at. It is a vector equal to (Speed * Direction)
Thank you SilverTabby! I have spent hours debugging direction and dozens of lines of code tweaking velocity to try simulate this one line of code.
I tried so many things, the others had such unintended behaviour, this worked like a charm. Thanks!
Thank you, SilverTabby. I was using multiple lines of code using Sin and Cos to do what you did in one line!
You can also use Vector3.Lerp to make all changes between the current speed and the target speed be smooth, something along the lines of
var constantSpeed : float = 1.0;
var smoothingFactor : float = 1.0;
function LateUpdate()
{
var cvel = rigidbody.velocity;
var tvel = cvel.normalized * constantSpeed;
rigidbody.velocity = Vector3.Lerp(cvel, tvel, Time.deltaTime * smoothingFactor);
}
Ah, great! And thanks for the clear up regarding the terms. I'll try this later tonight :)
in you example above, using a float constantSpeed makes things go crazy. No matter what value I set, the velocity is always 60, which is way too fast for my game. However, declaring constantSpeed as int works. any idea?
Answer by jonas.du · Sep 28, 2011 at 08:19 AM
Another way to solve your problem is the constant force component
Adding a constant force will only result in constant velocity if there is a corresponding counteracting force.
Answer by trono · Sep 28, 2011 at 07:59 AM
Hi and thanks for your reply!
I'm not sure how to use this solution when using physics for the movement and bounces though. If I have a [10,10,0] constant velocity the ball will just move up to the right until it hits a rigidbody and gets stuck in a corner or something. It won't bounce around at a set speed.
For future reference: avoid posting comments as answers, it messes with the site's search system, and it looks...unprofessional.
Also if your question was answered, make sure to check the answer as correct: it improves the search system, marks the question as completed, it makes people more likely to help you, and it gives me a nice little karma cookie :)
Answer by Hoorza · May 01, 2017 at 09:06 AM
Following SilverTabbys answer I have made this script:
public class Ball : MonoBehaviour
{
float constantSpeed = 10f;
public Rigidbody2D rb;
void Start ()
{
Rigidbody2D rb = GetComponent<Rigidbody2D>();
}
void Update ()
{
rb.velocity = constantSpeed * (rb.velocity.normalized);
}
}
it works like a charm so far. I can quickly adjust the variable to control balls speed this way. Just remember to drag in the Unity RigidBody2D component from your ball into the scripts slot. If someone know how to asign it within the script share the wisdom, but draging works just fine. Thanks.
@Hoorza Create a new tag, call it "Ball", and add it to your ball gameObject, then put this line of code in your Start or Awake function:
rb = GameObject.FindGameObjectWithTag ("Ball").GetComponent<Rigidbody2D> ();
or, If you made a custom class that you put on your ball you can find it like that,
rb = GameObject.FindObjectOfType<Ball> ().GetComponent<Rigidbody2D> ();
Your answer
Follow this Question
Related Questions
How do I make a sphere bounce forward without adding a lateral force? 1 Answer
Constant velocity -> weird physics interaction 1 Answer
How do I increase forward velocity of a 2D ball when it bounces? 1 Answer
How do I get velocity from a collision? 1 Answer
hinge joint bounce min velocity - physical explanation please 0 Answers