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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Unity Tutorial Part 3: Components
40 mins
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.
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.
Adding Gunplay
Unfortunately, the finer parts of diplomacy are lost on the flesh-eating antagonists of this game. It’s best you give the hero some firepower so he can protect himself on his terribly relaxing (terrible?) vacation.
First, you need to create a bullet. In the Hierarchy, click the Create button. From the drop-down, select 3D Object\Sphere to create a sphere in the Scene view.
Give it the name Projectile. With it still selected, check out the Inspector. You’ll notice a bunch of new components.
The three new components are:
- The Mesh Filter is a component that contains data about your model’s mesh and passes it to a renderer.
- The Mesh Renderer displays the mesh. It contains a lot of information about lighting, such as casting and receiving shadows.
- Finally, you’ll notice the sphere contains a Sphere Collider. This component serves as the GameObject’s boundaries.
Since you want the bullet to participate in Unity’s physics, it needs a Rigidbody.
Luckily, you’ve done this before. Click the Add Component button and select Rigidbody from the Physics category. Make sure to uncheck Use Gravity.
Since the marine will burn through lots of projectiles, drag it from the Hierarchy to the Prefabs folder in the Project Browser. Delete the projectile from the Hierarchy because you don’t need it now that it’s gone on to be a prefab.
At this point, you need to create a script to launch the projectile. In the Project Browser, select the Scripts folder then click the Create button. Choose C# Script and name it Gun. Double-click the file to launch the code editor.
This file needs a few properties underneath the class definition. Add the following:
public GameObject bulletPrefab;
public Transform launchPosition;
Again, when you create a public variable on a script, Unity exposes these variables in the editor. You will set the bulletPrefab
to the bullet prefab you just created, and you will set the launchPosition
to the position of the barrel of the Space Marine’s gun.
Next, add the following method:
void fireBullet()
{
// 1
GameObject bullet = Instantiate(bulletPrefab) as GameObject;
// 2
bullet.transform.position = launchPosition.position;
// 3
bullet.GetComponent<Rigidbody>().velocity =
transform.parent.forward * 100;
}
Let’s review this section by section:
-
Instantiate()
is a built-in method that creates a GameObject instance for a particular prefab. In this case, this will create a bullet based on the bullet prefab. SinceInstantiate()
returns a type ofObject
, the result must be cast into aGameObject
. - The bullet’s position is set to the launcher’s position — you’ll set the launcher as the barrel of the gun in just a moment.
- Since the bullet has a Rigidbody attached to it, you can specify its velocity to make the bullet move at a constant rate. Direction is determined by the transform of the object to which this script is attached — you’ll soon attach it to the body of the space marine, ensuring the bullet travels in same the direction as the marine faces.
Save and switch back to Unity. In the Hierarchy, expand the SpaceMarine GameObject and select the BobbleMarine-Body GameObject.
In the Inspector, click the Add Component button and near the bottom of the list of components, select Scripts. From the list of scripts, choose Gun.
You’ll see that your Gun script component has been added to the body of the marine. You’ll also notice there are two new fields: Bullet Prefab and Launch Position. Do those sound familiar?
Click the circle next to Bullet Prefab. In the Select GameObject dialog, click the Assets tab. Select Projectile from the resulting list. Now you have loaded the bullet and just need to set the launch position.
In the Hierarchy, hold the Alt key on PC or Option on Mac and click the disclosure triangle next to the BobbleMarine-Body. You’ll see a large list of child GameObjects. Look for Gun.
Select that GameObject and click the Create button. Choose Create Empty Child and rename it to Launcher. This new GameObject lives in the center of the gun’s barrel and represents where bullets will spawn from — feel free to move it around in the scene editor if you’d like to tweak the spawn position.
Keep all the GameObjects expanded and select BobbleMarine-Body so that the Inspector shows all the components. Drag the new Launcher GameObject into the Gun
component’s Launch Position field.
Notice that when you add the GameObject to a transform field, Unity finds and references the attached transform.
It’s official! The marine’s gun is locked and loaded. All that’s left is the firing code. Thankfully, it’s pretty easy.
Switch back to your code editor and open Gun.cs.
The gun should fire when the user presses the mouse button and stop when the user releases it.
You could simply check to see if the button is pressed in Update()
and call fireBullet()
if so, but since Update()
is called every frame, that would mean your space marine would shoot up to 60 times per second! Our space marine can shoot fast, but not that fast.
What you need is a slight delay between when you shoot bullets. To do this, add the following to Update()
:
if (Input.GetMouseButtonDown(0))
{
if (!IsInvoking("fireBullet"))
{
InvokeRepeating("fireBullet", 0f, 0.1f);
}
}
First, you check with the Input Manager to see if the left mouse button is held down.
1
, and for the middle mouse button, you’d pass in 2
.
If the mouse is being held down, you check if fireBullet()
is being invoked. If not, you call InvokeRepeating()
, which repeatedly calls a method until you call CancelInvoke()
.
InvokeRepeating()
needs a method name, a time to start and the repeat rate. InvokeRepeating()
is a method of MonoBehaviour
.
After that bit of code, add the following:
if (Input.GetMouseButtonUp(0))
{
CancelInvoke("fireBullet");
}
This code makes it so the gun stops firing once the user releases the mouse button. Save your work and return to Unity, then play the game.
Hold down the mouse button. You have bullets for days!