3D Games Programming - Unity Scripts

Scripts in Unity can be written in Javascript or C#. We're going to be going with C#, a Microsoft programming language. We have a full course on C#, which you can do by clicking the link on the left. But don't worry - you don't have to do the C# course first! The coding in Unity is not too difficult, and we'll have links along the way if you don't understand some of the concepts. Let's get started.

 

Adding Scripts

One thing to bear in mind with the coding aspect of Unity 3D games is that scripts belong to objects in your scenes. So, you might write a script and attach it to a player object. Or you might write a script and attach it to a car object. But these will be separate scripts. Generally, you don't write scripts for the entire game world. Just individual components in that world.

With that in mind, let's write a script for our car object. You'll then learn how to attach this script to the car.

There are lots of scripts out there for car movement, a lot of them quite complex, as you have to deal with things like wheel rotation. But the script we'll write will be very simple. We won't rotate our wheels. Our script will just move the car forward when the W key is pressed on the keyboard, and backward when the S key is pressed. We'll turn the car left and right via the mouse. Later, you'll see an example of a much more complex script for car movement.

There are a few ways to add a script to a game object. First, We'll do it via the Inspector.

Make sure your Car object from the previous lesson is selected in the Hierarchy. In the Inspector on the right, click the Add Component button:

Add Component button

When you click on Add Component, you'll see a box appear. This one:

List of Components

Type the word script into the search box at the top. You'll then see an item for New Script:

The Script component

Select New Script. In the Name box at the top, type CarMove as the script name. Then click Create and Add at the bottom.

Renaming a New Script

If you look at the Inspector, you'll see that a script component has been added:

A Script component added to a game object

To see where your script has gone, click the Assets folder in the Project area at the bottom. Your script will be there:

The Assets folder in Unity

To do a bit of housekeeping, create a new folder. Call it Scripts. Now drag your CarMove script into your new Scripts folder:

Dragging a script to a new folder

The script will disappear from the Assets folder and into the Scripts folder. Nice and tidy!

Now move into your scripts folder. Double click your new script:

Open a script by double-clicking

This will start your coding editor. (We're using Visual Studio. But see below if you're using a different Editor.). It can be a bit slow to load. But once it does, you should be looking at this:

Default code in Unity wuith a Start and Update method

You can use another editor rather than Visual Studio, if you don't have this. To use to a different editor, click on the Edit menu at the top of Unity. From the Edit menu, select Preferences. You'll see this dialog box appear:

Dialog box showing how to use a different coding editor in Unity

Select the External Tools tab on the left. At the top of the External Tools tab, the item you need is External Script Editor. Click the drop down to see something like this:

A list of available coding editors

This shows all the available editors you can use. There's also a Browse option, so you can search your computer for a suitable editor. (Visual Studio Code is quite a good editor. You may need to restart Unity before you can start using it, though.)

Back to the script. We don't actually need a Start method so you can delete that entirely. We don't need the first two using statements, either. So delete them, as well as the comments. You should be left with just this in your editor:

using UnityEngine;

public class CarMove : MonoBehaviour
{

void Update()
{

}

}

We we'll do first is to rotate the car when the mouse is moved. There is a handy inbuilt method called GetAxis. This belongs to the Input class. Let's set up a variable to hold all this. Add the following line between the round brackets of your Update method:

float rotateMouse = Input.GetAxis("Mouse X");

If you need a refresher on C# variables, see this page on our site:

C# Variables (Opens in new Tab.)

If you need a refresher on C# methods, see this page:

C# Methods (Opens in new Tab.)

In between the round brackets of GetAxis, you can use Mouse X or Mouse Y. Because we want to rotate the car left and right, we need Mouse X. This goes between double quotes. The Mouse X values are being assigned to a variable we've called rotateMouse. This is a float variable (meaning you can have with a point something on the end). The line ends with a semicolon. Miss the semicolon out and you'll get errors. Your code should look like this:

using UnityEngine;

public class CarMove : MonoBehaviour
{

void Update()
{

float rotateMouse = Input.GetAxis("Mouse X");

}

}

Now we need to put this rotateMouse variable to use.

The Inspector, if you remember, has a Transform component. This lets you position, rotate, and scale game objects. You can access the Transform component with code. You can then set values for the X, Y, and Z of, say, Rotation.

Add this line to your Update method, just below the one you already have:

transform.Rotate(0, rotateMouse, 0);

The values in between the round Brackets of Rotate are for it's X, Y and Z. We only want to rotate in the Y direction, so we set the X and Z to 0. The value we want to rotate is inside of our rotateMouse variable, which we are getting from the mouse.

ASIDE: You may be wondering why we're rotating the Y direction when we are getting the Mouse X. Shouldn't we be rotating X and not Y? You have to remember that, in the 3D world, the Y direction is like a pole stuck through your cube, from top to bottom. If you were to rotate the pole it would turn the cube around from left to right (or vice versa).

Here's what your coding window should look like now:

An Update method for Mouse X and Mouse rotation

Try it out. Save your work in your coding editor. Now click back onto Unity. Unity will refresh. Now switch from Scene view to Game view by clicking on the Game tab:

The Game tab being indicated in Unity

In Game view, click the Play button in the toolbar:

Tha Play Game button

Move your mouse from left to right. You should see something like in the short video below (9 seconds).

 

If you can't see your car in the scene, it means you have your camera position incorrectly. We'll fix that now.

 

Main Camera

Your scene needs at least one camera. (You can have as many as you want.) When you create a new project, you get a camera called Main Camera. You can drag your camera onto a game object. This allows you to see through the eyes of that object. This is good for things like first person shooters. But it can also come in handy for cars.

So, in the Hierarchy, drag the Main Camera onto your car:

Dragging the Main Camera into a game object

The Main Camera will then become a child of the car:

The Main Camera as a child of a game object

In the Inspector on the right, change the Transform values to these:

Position

X: 0
Y: 3
Z: -2

Rotation

X: 0
Y: 0
Z: 0

Scale

X: 1
Y: 2
Z: 0.5

When you click on the Game tab, your view of the car should be this:

A boxcar sitting on a Plane in Game view

Click Play and see what it looks like when you move your mouse.

Experiment with the camera's position, though. To move the camera forward, manipulate the blue arrow in Scene view. This moves the camera in the Z direction. To move the camera up, manipulate the Green arrow in Scene view. This moves the camera in the Y direction.

Now let's get the car moving back and forward.

 

Moving the Car

Go back to your coding editor. At the top, above the Update method but inside of the Class, add the following line:

public float speed = 2.0f;

This sets up a float variable called speed. We need this for the speed of the car. We've set it to a sedate 2.0f. (The f on the end stands for float. Miss this out and you'll get errors.) We've made speed public, but we're going to change this.

Your code should look like this:

C# code with a public float speed varaible added

Save your work in the coding editor.

To see what a public variable does, switch back to Unity. When Unity refreshes, select your car. Now have a look at the Inspector. You'll see the speed variable is there:

The Inspector showing the result of a public variable

This means you can delete the 2 and enter a new value for speed, all through Unity. The alternative is to go back to your coding editor, change the value for speed there, come back to Unity, and then wait for it to refresh.

However, there is a problem with making your variable public. You'll probably have lots of scripts for your game. If you have another speed variable on some other game object, then the two may clash and cause you problems. One alternative is to make the speed variable private.

So, in your coding editor, change the keyword public to private:

private float speed = 2.0f;

Save your work in the coding editor. Come back to Unity and notice the Inspector when your car is selected:

The Inspector showing what happens when a public variable is made private

The speed variable has vanished, meaning you can no longer set a value for it in Unity.

There is a third option - SerializeField. Change the keyword private to [SerializeField]:

[SerializeField] float speed = 2.0f;

SerializeField needs to go between a pair of square brackets.

Save your changes in your coding editor and go back to Unity. The speed variable will reappear.

A SerializeField variable is still private. Which means that no other script can change it. But you still get the advantage of being able to change the value in Unity.

You don't need to have all your variables showing up in Unity, though. It's really just a handy way to test things out. Mostly, you should keep your variables private.

The default, by the way, is private. If you just had this:

float speed = 2.0f;

the speed variable would be private.

 

Get a Keypress

We're going to use if statements to move the car. So, if you need a refresher on C# if statements, see here on our site:

C# if statements (opens in new tab)

You've already used Input.GetAxis. But there is also an Input.GetKey. This lets you detect which key on the keyboard is being pressed. It's quite easy to use. It's just this:

Input.GetKey(KeyCode.W)

In between the round brackets of the GetKey method, you type KeyCode then a dot. After the dot, select which key you want to detect. All of this gets wrapped in an if statement.

Add this to your Update method, just below the lines you already have:

if (Input.GetKey(KeyCode.W)) {
}

If that's true, the W key is pressed on the keyboard, then we can move our car.

But what do we put inside of the curly brackets of the if statement?

In the Inspector, each game object has components. One of these is the Transform. You have been playing around with Position, Rotation, and Scale of the Transform component. But you can access the transform object via code. With code, instead of the Position, Rotation, and Scale, there is a Translate method.

transform.Translate();

In between the round brackets of Translate, you first need a Vector3 object. What's a Vector3 object? This is just an object that has three values for X, Y, and Z. If you wanted to move forward or backward, you'd set the Z direction to 1 and all the others to 0:

Vector3(0, 0, 1);

However, there are some handy shortcuts:

Vector3.forward
Vector3.back
Vector3.left
Vector3.right

But just using Vector3 won't get our car moving. This is just the direction you want it moving. We need to multiply the Vector3 direction by our speed variable:

transform.Translate(Vector3.forward * speed);

If you left it at that, you'd find that your car would go whizzing off the end of your plane. To fix it, you need to multiply by something called Time.deltatime:

transform.Translate(Vector3.forward * speed * Time.deltatime);

Time.deltatime has to do with how many frames per second a graphics card can handle. The best ones can handle a lot, a cheap one, not so many. Time.deltatime ensures that whatever card you have, the car will move at the same rate.

So, add that between the curly brackets of your if statement:

if (Input.GetKey(KeyCode.W)) {

transform.Translate(Vector3.forward * speed * Time.deltaTime);

}

Try that out. Save your work in your coding editor and then go back to Unity. Play your game and press the W key on your keyboard. Keep it held down for a while because it will look like nothing is happening. (We have no frame of reference in our scene. We'll fix this soon.)

Before testing it out, let's add another if statement to make the car go back when the S key is pressed on the keyboard. Add this:

if (Input.GetKey(KeyCode.S))
{

transform.Translate(Vector3.back * speed * Time.deltaTime);

}

Your code should look like this:

Unity C# code to detect keyboard key presses

Save your work and try it. Go back to Unity and the Game tab. Press the Play button and you should find that you can move around, as shown in the short video below (21 seconds):

 

You can change the speed of your car while the game is playing. In Scene view, select the car. Locate the speed value in the Inspector.

It's set to a default of 2, which is really slow. Click on the Game tab and play your game. Now click inside the speed text box and change it to a value of, say, 10. Press the enter key on your keyboard to confirm the new value. Now click back on your game and your car should move at the new speed. (If it doesn't, make sure the speed text box is not highlighted in blue. Just click out of it somewhere and then back on your game.)

In the next lesson, we'll create some sort of racetrack.

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