# C# Change speed of object

## Recommended Posts

I've got a ball object and I want to be able to manipulate the ball's speed (both speed up and slow down) based on different pickups dropped in the game. I'm not sure how best to do this. Here is my code for the Ball class:

public class Ball : MonoBehaviour
{

private bool hasStarted = false;

// Use this for initialization
void Start ()
{
}

// Update is called once per frame
void Update ()
{
if (!hasStarted)
{
//Lock the ball relative to the paddle.
//Wait for a mouse press to launch.
if (Input.GetMouseButtonDown (0))
{
hasStarted = true;
this.GetComponent<Rigidbody2D> ().velocity = new Vector2 (2f, 10f);
}
}

}

void OnCollisionEnter2D (Collision2D collider)
{
//use this vector2 to adjust the velocity so the ball does not get stuck in a vertical bouncing loop
Vector2 tweak = new Vector2 (Random.Range(0f, 0.2f),Random.Range(0f, 0.2f));
if (hasStarted)
{
AudioSource audio = this.gameObject.GetComponent<AudioSource>();
audio.Play();
this.gameObject.GetComponent<Rigidbody2D>().velocity += tweak;
}

}
}

I just need to know how to manipulate the speed for this class. I'm not sure if how I have it set up now is the best way to manage movement of the ball object or if I should modify it to accommodate for speed manipulation.

##### Share on other sites
Posted (edited)

Good to see you are making progress. Now you enter the realm of vector math.

There is some things I must double check you know. A vector has both magnitude and direction. We can think of any vector as a line, that points in a direction and has a length.

This image shows the vector (2,2) and how it starts from (0,0) to make an arrow pointing at 45 degrees or NE. All the vectors you work with act like this, even the 3D ones.

Next you need to know what a scalar is. A scalar is any single value like 1 or 48 or 9.2 etc. It is a number. The reason it is called a scalar is because it scales the vector. Like this:

(2,2) * 2 = (4,4) //See it is double the size now, it has scaled:

If your ball's velocity is (2,2) and you multiply it by 2, it would double in speed.

Lets say your speed boosts makes the ball only a little bit faster each time; it would look like this:

//To make things shorter lets add a pointer to the rigidbody
Rigidbody2D BallBody;

//Rigid bodies have to be assigned at start
void Start(){
BallBody = this.gameObject.GetComponent<Rigidbody2D>().velocity;
}

//Now the code for speed up
void MakeBallFaster(){
//we will add 0.2 of the balls speed to the object
BallBody.velocity = BallBody.velocity* 1.2f;//You can also make it a variable
}

//Similar code to slow it down
void HalfBallSpeed(){
BallBody.velocity = BallBody.velocity* 0.5f;
}

Most programmers like having a speed variable, that constantly scales the velocity and can be used to limit speed. Advanced:

Spoiler


//Make the speed varaible publick to easy edit it
public Speed = 0f;
private SpeedMax = 100f;//This is the limit

//To make things shorter lets add a pointer to the rigidbody
Rigidbody2D BallBody;

//Rigid bodies have to be assigned at start
void Start(){
BallBody = this.gameObject.GetComponent<Rigidbody2D>().velocity;
}

//Now the code for speed up
public float SpeedUp(float SpeedAmount){
Speed = Speed + SpeedAmount;
//Speed can only be added upto the max
if (Speed > SpeedMax)
{
Speed = SpeedMax; //mow it can't be more than 100
}
return Speed;
}

//Similar code to slow it down
public float SpeedDown(float SpeedAmount){
Speed = Speed - SpeedAmount;
//Speed can only be added upto the max
if (Speed < -SpeedMax)
{
Speed = -SpeedMax; //mow it can't be smaller than -100
}
return Speed;
}

//The above functions are just limits, lets use them
void Start(){
//When the game starts we wan't the ball to move at the avrage speed
//Lets say 0.1 blocks per tick is normal
BallBody.velocity = Vector3.Up * SpeedUp(0.1f);
}

//When it hits it should speed up
void OnCollisionEnter2D(){
BallBody.velocity = BallBody.velocity * SpeedUp(0.1f);
}

Edited by Scouting Ninja

##### Share on other sites

This is pretty close to what I ended up with last night. The major difference is that I was doing it in a different script titled SlowBall. Which brings me to a structure question. I'm going to have about 6 different power ups. Some of them simply change the ball's behavior, such as speed in this case. Others make multiple balls and do various different things with them, and one of them stops the ball on the paddle and gives the player an aiming control. Knowing all this, would it be best to have an individual script that handles everything to do with each one of these? Or should I do something like you have done here where I would add methods directly on the Ball script, and then just activate them when there is a collision with a specially tagged game object or something?

##### Share on other sites
15 hours ago, ethancodes said:

would it be best to have an individual script that handles everything to do with each one of these?

How  you want. I did a test a while ago on how performance intense Unity scripts are and they are very light.

Maybe you would like to have them under inheritance, like you did with bricks. Programmers like this way because it is more flexible and keeps code easier to read.

##### Share on other sites

I've got this pretty close I think. One issue I'm still having that I'm a bit unsure about is that when I set the ball's speed to .5 to slow it down, it doesn't just slow the ball down to half speed. It continuously keeps slowing down and falling to the bottom of the screen, eventually just landing on the paddle. I'm assuming I need to change how the ball is moved because it seems that at it's decreased speed, it doesn't have enough force to keep it moving? I want it to continue moving and bouncing off of walls, bricks, and the paddle, but at a decreased speed.

##### Share on other sites
3 hours ago, ethancodes said:

It continuously keeps slowing down and falling to the bottom

Do you keep slowing it down? Remember that you should only half the speed once.

Can I see the part of the code that calls the slowdown?

##### Share on other sites

Here is the SlowBall powerup code:

public class SlowBall : MonoBehaviour {

private int timer = 2;

GameObject ball;

// Use this for initialization
void Start () {
ball = GameObject.FindGameObjectWithTag("Ball");
}

void OnCollisionEnter2D (Collision2D collision)
{
if (collision.gameObject.tag == "Paddle" || collision.gameObject.tag == "Ball")
{
ball.GetComponent<Ball>().Speed = .5f; //reduce ball speed
ball.GetComponent<Ball>().PowerUpTimer(timer); //set time that power up is active
Destroy(gameObject); //destroy power up object
}
}

}

And then this is the ball's code. I believe this is actually where the problem is. I think it has to do with how I'm putting the speed variable in there. It seems like I have the same thing multiple times.

public class Ball : MonoBehaviour
{

private bool hasStarted = false;

public float Speed { get; set; }

// Use this for initialization
void Start ()
{
Speed = 1;
}

// Update is called once per frame
void Update ()
{
if (!hasStarted)
{
//Lock the ball relative to the paddle.
//Wait for a mouse press to launch.
if (Input.GetMouseButtonDown (0))
{
hasStarted = true;
this.GetComponent<Rigidbody2D> ().velocity = new Vector2 (2f, 10f) * Speed;
}
}

}

void OnCollisionEnter2D (Collision2D collider)
{
//use this vector2 to adjust the velocity so the ball does not get stuck in a vertical bouncing loop
Vector2 tweak = new Vector2 (Random.Range(0f, 0.2f),Random.Range(0f, 0.2f));
if (hasStarted)
{
AudioSource audio = this.gameObject.GetComponent<AudioSource>();
audio.Play();
this.gameObject.GetComponent<Rigidbody2D>().velocity += tweak;
this.gameObject.GetComponent<Rigidbody2D>().velocity *= Speed;
}

}

public IEnumerator PowerUpTimer (int delay)
{
yield return new WaitForSeconds(delay);
Speed = 1;
this.gameObject.GetComponent<Rigidbody2D>().velocity *= Speed;

}
}

##### Share on other sites
	void OnCollisionEnter2D (Collision2D collider)
{
//use this vector2 to adjust the velocity so the ball does not get stuck in a vertical bouncing loop
Vector2 tweak = new Vector2 (Random.Range(0f, 0.2f),Random.Range(0f, 0.2f));
if (hasStarted)
{
AudioSource audio = this.gameObject.GetComponent<AudioSource>();
audio.Play();
this.gameObject.GetComponent<Rigidbody2D>().velocity += tweak;
this.gameObject.GetComponent<Rigidbody2D>().velocity *= Speed;﻿
}

}

Here you keep effecting the speed.

To explain it starts as Vector2 (2f, 10f) then 1 bounce it = (2.2f,10.2f) * 0.5f = (1.1f, 5.1f) Then the next bounce it is (1.3f, 5.3f) *0.5f = (0.65f, 2.65f) etc.

The way you are trying to use the speed here is as if 1f = full speed and 0.5f = half speed. To do it like this you need some kind of MaxSpeed that can be effected by this.

So lets try this: Vector2 (2f, 10f) , this at the start so I assume it is what you want as the normal speed. To find speed we use﻿﻿ you use the Pythagorean theorem: (2*2=4 , 10*10 =100) the root of 104 = 10.198f

At the top we now add this:

//Place This some where at the top
float MaxSpeed = 10.198f;

void OnCollisionEnter2D (Collision2D collider)
{
//use this vector2 to adjust the velocity so the ball does not get stuck in a vertical bouncing loop
Vector2 tweak = new Vector2 (Random.Range(0f, 0.2f),Random.Range(0f, 0.2f));
if (hasStarted)
{
AudioSource audio = this.gameObject.GetComponent<AudioSource>();
audio.Play();
//So now we turn the velocity into a direction with the speed of 1 on collision
this.gameObject.GetComponent<Rigidbody2D>().velocity = this.gameObject.GetComponent<Rigidbody2D>().velocity.normalized;
//Next we take our max speed and set the velocity to current speed * MaxSpeed
this.gameObject.GetComponent<Rigidbody2D>().velocity *= Speed*MaxSpeed;// 0.5f*10.198 = 5.099f

//The tweek can be added now
this.gameObject.GetComponent<Rigidbody2D>().velocity += tweak;
}

}﻿

To explain: if the ball starts with Vector2 (2f, 10f) it has a magnitude/ speed of 10.198f and normalized it is (0.196, 0.981). Normalized can be seen as the direction only; because it is a direction with speed of 1.

The length/ speed of a vector = Pythagorean theorem.

(0.196, 0.981) * 10.198(2f, 10f); So direction*speed = vector of speed and direction.

So here: this.gameObject.GetComponent<Rigidbody2D>().velocity.normalized; we take the velocity (2f, 10f) and divide it by it's own speed (10.198f) that is what normalized means. We get: (0.196, 0.981).

Here: this.gameObject.GetComponent<Rigidbody2D>().velocity *= Speed*MaxSpeed; our velocity is (0.196, 0.981) and now we take (10.198 *0.5 = 5.099); and use that as our new speed. (0.196, 0.981) * 5.099 = (1f ,5f) or 50% of (2f, 10f)

Normally speed isn't used like a percentage like here. Instead speed would have been a value.

Normalizing before multiplying with speed is always a good idea. Later you will also start using Delta time for frame-rate independent movement.

If you don't understand what I did above then try this: https://www.khanacademy.org/math/linear-algebra

##### Share on other sites

That's what I was afraid of. I figured I was doing something wrong there, I just wasn't sure how to fix it. I get why you did all of this. I have a decent understanding of linear algebra, just a very poor understanding of when and how to apply it. But I think I'm starting to understand a little more as I continue to work on moving things around. Thanks again for the help!

##### Share on other sites
9 hours ago, ethancodes said:

I have a decent understanding of linear algebra, just a very poor understanding of when and how to apply it.

That is one of the best things about making games, you actually get to see how this math you spend years learning in school actually works.

If you already understand linear algebra then Khan academy is often too boring to stick with. In that case Math Is Fun is a much lighter and more practical site:  https://www.mathsisfun.com/algebra/vectors.html

The important part of using vectors is knowing that the magnitude is speed when working with movement. So every vector already has a speed and a direction.

## Create an account

Register a new account

• 10
• 15
• 14
• 18
• 15
• ### Similar Content

• By Pixeye
I wrote an extension for unity inspector that allows to group/fold variables.
Available on github  , cheers!

• I'M interested in programming tools (For animation, UI, etc). Can anyone suggest me the resources where I can start learning or which technologies I need achive it.

Thanks,
Rakshit
• By Paszq
Group photo of some of the characters and creatures currently living in Arpago
• By JuliaAxt
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class TapController : MonoBehaviour {
public float tapForence = 10;
public float tiltSmooth = 5;
public Vector3 startPos;
Rigidbody2D Rigidbody;
Quaternion downRotation;
Quaternion forwardRotation;
private void Start() {
Rigidbody = GetComponent<Rigidbody2D>();
downRotation = Quaternion.Euler(0, 0, -90);
forwardRotation = Quaternion.Euler(0, 0, 35);

}
private void Update() {
if (Input.GetMouseButtonDown(0))
{
transform.rotation = forwardRotation;
Rigidbody.AddForce(Vector2.up * tapForce, ForceMode2D.Force);   (The name tapForcedoes not exist in current context)
}
transform.rotation = Quaternion.Lerp(transform.rotation, downRotation, tiltSmooth * Time.deltaTime);
}
}
void OnTriggerEnter2D(Collider2D col){
if (col.gameObject.tag == "scoreZone")
{
// register a score event
// play a sound
}
{
Rigidbody.simulated = false;   (Rigidbody does not contain a definition for `simulated´)
//play a sound
}
}

}

• By Paszq
A bunch of chests full of sweet loot :)