Unity - Brakes, Engine Sounds

We've added wheels and a car body in previous lessons. In this lesson, we'll first add some brakes and the add some sounds for the engine.

 

Brakes

Go back to your CarControl code, then. In the FixedUpdate method, just below your two Input lines, add this new one:

bool brake = Input.GetButton("Jump");

This time, we use GetButton after Input, instead of GetAxis. This allows us to detect when the spacebar on the keyboard was pressed (Jump is the default name from the Edit > Project Settings menu at the top of Unity). If the Jump key (spacebar) is pressed, the brake Boolean variable will be true.

Now add these two if statements inside of your foreach loop, just before the DoTyres call:

if (brake == true) {

element.leftWheel.brakeTorque = 1000;
element.rightWheel.brakeTorque = 1000;

}

if (brake == false) {

element.leftWheel.brakeTorque = 0;
element.rightWheel.brakeTorque = 0;

}

Your FixedUpdate method should look like this (new lines are highlighted):

C# Unity code showing how to add brakes to a car

The if statements just test whether the brake variable is true or not. If it is, we have these lines:

element.leftWheel.brakeTorque = 1000;
element.rightWheel.brakeTorque = 1000;

The leftWheel and rightWheel parts are Wheel Colliders, remember. There are lots of things you can do with Wheel Colliders. In fact, when you type a dot after leftWheel or rightWheel, you'll see a popup list of all the things you can do with a Wheel Collider. Here's the full list:

A list of properties and methods for a Unity Wheel Collider

The cubes icons next to a name are methods while the wrench symbols are all properties. If you were to click on brakeTorque, you'd see a tooltip appear. This one:

The tooltip tells you that brakeTorque is going to be a float. So you couldn't store a string value in it like "twenty", or try to return the value to a string. So you couldn't do this:

element.leftWheel.brakeTorque = "Twenty";

Or this:

string val = element.leftWheel.brakeTorque;

You'd have to do this, if you wanted to get at the value:

float = element.leftWheel.brakeTorque;

So, if you want to use any of the wrench items on the list, pay attention to the variable type.

Anyway, one of the items on the list is brakeTorque, which is a float. We've set ours to 1000. But you might want to experiment with this number.

The second if statement just detects if brake is false. It will be false when you take your finger off the spacebar. In which case, we need to set the brakeTorque back to zero. If we don't, the car would be stuck with its brakes on.

Save your code and go back to Unity. Play your game again and drive your car. Head to one of your cubes and hit the spacebar on your keyboard to apply the brakes. Your car should stop.

OK, now let's add some sound.

 

Coding for Car Engine Sounds

Adding engine sounds to your car can be quite tricky because you have to detect when the revs are increasing or decreasing. It can get insanely complicated. So we'll stick with something simple for our engine sound. (We could leave the sound off altogether and say it's an electric car!)

We'll need an engine sound first. There's a good engine sound pack here on the Unity Asset store, by slaczky - Skril Studio.

Rotary-x8-free-engine-sound-pack-106119

Download and install the sound pack.

NOTE: The Package Manager has an annoying habit of telling you that there are no files. Make sure My Assets is selected at the top and then click the Refresh button below:

Once installed, have a look in the Project area of Unity. You should see a new folder appear called Car Engine Sound - Rotary x8 Free. Expand the Assets > Audio folder. You'll then see some audio files you can use. There's also a folder called Interior that has even more sounds inside of it:

Audio files showing in the Project area of Unity

We'll need one of these audio files shortly.

Now click on CAR-ROOT in the Hierarchy. With CAR-ROOT selected, click the Add Component button again in the Inspector on the right. Search for Audio Source and add one of these components:

Check the boxes for Play on Awake and Loop. Then click the tiny circle on the right of Audio Clip, as indicated by the first arrow in the image above. You'll see a Select Audio Clip dialog box appear:

A selected audio clip

All those sound files you downloaded should be on the list. Select one of the files (int_high_on seems to work well). Close down the dialog box and go back to your coding window.

Add these variables with all those others (just under Transform massCenter will do):

private float topSpeed = 100;
private float currentSpeed = 0;
private float pitch;
private AudioSource engine;

These are all private variables. The first three are floats and the last one an AudioSource. The topSpeed variable doesn't set the top speed of your car. We're just going to use it as a divider to change the engine pitch. The other variables are called currentSpeed, pitch, and engine.

In your Start method, add this line:

engine = GetComponent<AudioSource>();

This just Gets that AudioSource component you added in the Inspector and stores it in the engine variable.

In your FixedUpdate method, add these three lines just below your Jump one but before the foreach loop:

currentSpeed = rb.velocity.magnitude * 3.6f;
pitch = Mathf.Lerp(0, 1, currentSpeed / topSpeed);
engine.pitch = pitch * 0.5f;

Your code should look like this (new lines are highlighted):

C# Unity code to change the pitch of an audio file to simulate an engine sound

Bear in mind what we're doing with this audio code - changing the pitch of an audio file to simulate the sound of an engine going up and down as we increase or decrease the revs.

Let's got through those three lines of code, then. The first is this:

currentSpeed = rb.velocity.magnitude * 3.6f;

This gets how fast we're going. The rb is our Rigidbody, remember, the one attached to CAR-ROOT. A Rigidbody has a velocity.magnitude you can access to get you the speed. We're multiplying by a figure of 3.6 to get a value in kilometres. But the speed we're currently going gets stored in our currentSpeed variable.

Next, we have this:

pitch = Mathf.Lerp(0, 1, currentSpeed / topSpeed);

We could have missed out the Lerp part and just had this:

pitch = currentSpeed / topSpeed;

But it's always nice to do a bit of lerping, as it smooths out any harshness. We covered Lerp in another tutorial: Lerp (near the bottom of the page)

But the line sets a float value for our pitch variable by dividing the currentSpeed by the topSpeed.

Finally, we have this line:

engine.pitch = pitch * 0.5f;

This is a bit of a fudge, but it just halves the pitch so that the sound doesn't get to the higher pitches to early. Try entering higher or lower numbers here to see what happens (anything between 0.1 and 0.9).

But save your code and go back to Unity. Try your game out. Drive the car and keep your finger on the W key. Then decrease the speed by pressing the S key. You should hear the engine noise going up and down. Hit the brakes by pressing your spacebar and the engine noise will stop altogether. The short video below shows what you should have:

 

The engine noise is not ideal, but a close approximation to engine sounds is very hard to code. Ours isn't too bad for just a few lines of code!

 

OK, now let's move on and add some roads for our car to drive on.

<--Back to the Unity 3D Course Contents Page