Unity Tutorial Part 3: Components

In the final part of our Unity tutorial series, you’ll learn how to make your first game in Unity with C# from scratch: a twin-stick shooter called Bobblehead Wars! By Brian Moakley.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 5 of this article. Click here to view the first page.

Accessing Input From Code

Now to actually implement the control scheme. In the Project Browser, double-click the PlayerController script to launch the editor.

When the code editor opens, you’ll see your first script. Every new script contains empty implementations for Start() and Update().

Look for a blank line below the first { (a.k.a., “curly bracket”) — that’s the class definition. Add the following code there:

public float moveSpeed = 50.0f;

If your script throws an error, carefully review the code to make sure you didn’t miss, forget or mess up something.

Note: If you are new to programming languages, it’s critical that you copy everything exactly as it is written. Any deviation will produce errors. Programming languages are very precise and become grumpy when you use the incorrect case or syntax.

moveSpeed is a variable that determines how fast the hero moves around in the arena. You set it to a default value of 50 that you can change later in Unity’s interface.

Now, to write the actual moving code. In Update(), add the following:

Vector3 pos = transform.position;

This bit of code simply gets the current position of the current GameObject — in this case, the space marine since that is what this script is attached to — and stores it in a variable named pos. In Unity, a Vector3 encapsulates the x, y and z of a GameObject, i.e., the object’s point in 3D space.

Now comes the tricky part. Add the following after the previous line:

pos.x += moveSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
pos.z += moveSpeed * Input.GetAxis("Vertical") * Time.deltaTime; 

When you move the object, it’ll only be on z- and x-axes because y represents up and down. Because there are two different input sources (“Horizontal” for left and right, and “Vertical” for up and down), you need to calculate values for each axis separately.

Input.GetAxis("Horizontal") retrieves a value from the Horizontal component of the Input Manager. The value returned is either 1 or -1, with 1 indicating that a positive button in the Input Manager is being pressed. According to the settings you saw defined earlier, this is either the right arrow or d keys. Similarly, a value of -1 indicates that a negative button is being pressed, meaning it was either the left arrow or the a key.

Whatever the returned value may be, it’s then multiplied by the moveSpeed and added to the current x position of the GameObject, effectively moving it in the desired direction.

The same thing happens with Input.GetAxis("Vertical"), except it retrieves a value from the vertical component of the Input Manager (indicating the s, down, w or up keys), multiplies this (1 or -1) value by the moveSpeed and adds it to the z position of the GameObject.

So what’s with Time.deltaTime? That value indicates how much time has passed since the last Update(). Remember, Update() is called with every frame, so that time difference must be taken into account or the space marine would move too fast to be seen.

TL/DR: Time.deltaTime ensures movement is in sync with the frame rate.

By default, Unity considers one point to be equal to one meter, but you don’t have to follow this logic. For instance, you may be making a game about planets, and that scale would be way too small. For the purposes of simplicity in this tutorial, we have sized our models to follow Unity’s default of one point per meter.

What do these numbers mean?

Now that you’ve altered the location, you have to apply it to the SpaceMarine GameObject. Add the following after the previous line:

transform.position = pos;

This updates the SpaceMarine GameObject’s position with the new position.

Save the script and switch back to Unity. You may be tempted to run your game, but there’s a slight problem. The camera is not positioned correctly.

In the Hierarchy, select the Main Camera, and in the Inspector, set Position to (9.7, 53.6, 56.1) and Rotation to (30, 0, 0). I determined these values by moving the camera around manually and looking at the Camera preview in the lower right until I was happy with the result.

In the Camera component, set Field of View to 31. This effectively “zooms in” the view a bit.

Now it’s time to give your game a test run. Look for the play controls at the center-top of the editor. Click the Play button.

Note: You’ll notice the controls give you two more options: Pause and pause stepper. Pause allows you to, well, pause your game in motion. The stepper allows you to step through the animation one frame at a time and is especially useful for debugging animation issues.

Now, look at the Game window and move your character by pressing the Arrow keys or WASD keys. Behold… life!

The Game window is where you actually play the game. There are two life-and-death details to keep in mind as you play.

First, when you start playing, the interface becomes darker to give a visual queue that you’re in play mode.

Second, when you play your game. you can change anything about it (including changing values on components in the inspector) but, when you stop playing the game, ALL YOUR CHANGES WILL BE LOST. This is both a blessing and a curse. The blessing is that you have the ability to tweak the game without consequence. The curse is that sometimes you forget you’re in play mode, continue working on your game then, for some reason, the game stops. Poof! Buh-bye changes!

Thankfully, you can (and should) make play mode really obvious. Select Edit\Preferences on PC or Unity\Preferences on Mac to bring up a list of options.

Select the Colors section. Look for Playmode tint. Click the color box next to it, and then give it an unmistakable color — I prefer red. Now play your game to see if it’s conspicuous enough.

The Game window

Camera Movement

There’s only one problem with the space marine’s movement: He will slip off screen. You want the camera to follow the hero around the arena, so he doesn’t get away from you.

With a little scripting, you can keep the marine in focus.

First, make sure you’re not in play mode – to stop play mode, select the play button again.

In the Hierarchy, click the Create button and select Create Empty. Name it CameraMount.

The basic idea is you want CameraMount to represent the position the camera should focus on and have the camera be relative to this position.

Initially you want the camera to focus where the space marine is, so let’s configure the CameraMount to be at the exact same position as the space marine.

To do this, select the space marine, click on the Gear button to the upper-right of the Transform component, and select Copy Component

Then select the CameraMount, click on the Gear button to the upper right of the Transform component, and select Paste Component Values:

Next, drag the Main Camera GameObject into the CameraMount GameObject.

Great! Now as you move the player around, you can move the CameraMount to move with the player, and the camera will track the player. You just need to write a script to do this.

With the CameraMount selected, click the Add Component button in the Inspector and select New Script. Call it CameraMovement and then click Create and Add.

Note: When you make a new script by clicking the Add Component button, Unity will create the script in the top level of your assets folder. Get into the habit of moving assets into their respective folders the moment you make or see them.

Drag your new file from the top level of the assets folder into the Scripts folder.

Double-click the CameraMovement script to open it in your code editor. Underneath the class definition, add the following variables:

public GameObject followTarget;
public float moveSpeed;

followTarget is what you want the camera to follow and moveSpeed is the speed at which it should move. By creating these as public variables, Unity will allow you to set these within the Unity editor itself, so you can set the followTarget to the space marine and fiddle with the moveSpeed to your heart’s content, as you’ll see shortly.

Now add the following to Update():

if (followTarget != null) 
{
  transform.position = Vector3.Lerp(transform.position, 
    followTarget.transform.position, Time.deltaTime * moveSpeed);
}

This code checks to see if there is a target available. If not, the camera doesn’t follow.

Next, Vector3.Lerp() is called to calculate the required position of the CameraMount.

Lerp() takes three parameters: A start position in 3D space, an end position in 3D space, and a value between 0 and 1 that represents a point between the starting and ending positions. Lerp() returns a point in 3D space between the start and end positions that’s determined by the last value.

For example, if the last value is set to 0 then Lerp() will return the start position. If the last value is 1, it returns the end position. If the last value is 0.5, then it returns a point halfway between the start and end positions.

In this case, you will supply the camera mount position as the start and the player position as the end. Finally, you multiply the time since the last frame rate by a speed multiplier to get a suitable value for the last parameter. Effectively, this makes the camera mount position smoothly move to where the player is over time.

Save your code and return to Unity. Select CameraMount in the Hierarchy, and look in Inspector. You’ll see two new fields named Follow Target and Move Speed. As mentioned earlier, these were automatically derived by Unity from the public variables you just added to the script. These variables need some values.

With the CameraMount still selected in the Hierarchy, drag SpaceMarine to the Follow Target field and set the Move Speed to 20.

Play your game to see what’s changed.

The marine is a real superstar now, complete with a personal camera crew. Granted, he can’t turn, and he walks right through objects just like Kitty Pryde, but these are easily solvable issues that you don’t have to tackle now.

Note: The bigger the move speed, the faster the camera mount will move to the player. The smaller, the more the camera will “lag” behind the space marine’s position, letting the player “jump ahead” of the camera. Try changing the move speed to a smaller value, like 2, and see what happens for yourself!