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!

5/5 2 Ratings · Leave a Rating

Version

  • C# 7.2, Unity 2018.1, Unity
 
Please note, this is a STATIC archive of website www.raywenderlich.com from 08 May 2019, cach3.com does not collect or store any user information, there is no "phishing" involved.

This is an excerpt taken from Chapter 1, “Hello Unity” of our book Unity Games by Tutorials, newly updated for Unity 2018.1, which walks you through creating four Unity games from scratch — and even shows you how to develop for VR in Unity. Enjoy!

Welcome to the third and final part of this Unity mini-series! In this tutorial, you’ll learn all about Components in Unity while you give your hero free reign to blast the landscape with bullets!

This tutorial continues on from the previous tutorial, Unity Games, Part 2: GameObjects.

At this point, you’ve accomplished your goal of having all the main actors ready, but it’s essentially an empty stage. Sure, you might win some avant-garde awards for a poignant play on the lack of free will, but that’s not going to pay the bills.

In this tutorial, you’ll add some interactivity to your game through the use of Components, which are fundamental to Unity game development. If you were to think of a GameObject as a noun, then a component would be a verb, or the part that performs the action; a component does something on behalf of a GameObject.

You’ve learned a bit about components already. In the previous two parts in this tutorial series, you learned how each GameObject has one required component: The Transform component, which stores the GameObject’s position, rotation and scale.

But Unity comes with far more components than that. For instance, there’s a light component that will illuminate anything near it. There’s an audio source component that will produce sound. There’s even a particle system component that will generate some impressive visual effects. And, of course, if there isn’t a component that does what you want, you can write your own.

In this tutorial, you’ll learn about several types of components, including the Rigidbody component, the script component, and more. By the end of this tutorial, your marine will be running and gunning!

Getting Started

If you completed the last tutorial, open your current Bobblehead Wars project to pick up where you left off. If you got stuck or skipped ahead, download the materials for this course using the links at the top or bottom of this page, open the Bobblehead Wars starter project from this tutorial’s resources.

Currently, the space marine only knows how to stand like a statue. He needs to move around if he’s going to avoid being some alien’s snack.

The first thing you’ll add is a Rigidbody component, which opts the GameObject into the physics engine. By adding it, you’ll enable the GameObject to collide with other GameObjects.

Adding the Rigidbody Component

In the Hierarchy, select the SpaceMarine GameObject and click the Add Component button in the Inspector.

You’ll see many different categories. When you know which component you need, simply search by name. Otherwise, select one of the categories and pick the best option.

Click the Physics category then select Rigidbody.

You’ll see that a Rigidbody component was attached to the GameObject. Congratulations! You’ve added your first component.

Each component has its own set of properties, values and so forth. These properties can be changed in the Inspector or in code. Components also have their own icons to make it easy to determine their type at a glance.

You’ll notice some icons in the top right-hand corner of each component, like this:

The first icon is the Reference icon. Click it. It’ll open another window with the documentation page for that component. If you installed the documentation, this page is on your computer — and, yes, the search bar works.

The second icon is a new feature in Unity 2018. This is the presets button. As you customize your components, you may prefer a certain, preset, configuration created previously.

In the Rigidbody component, check the IsKinematic checkbox. Also, uncheck the Use Gravity option. You’ll learn about those options in a moment. But once you have unchecked them, click the presets button.

You can save that configuration as a preset, then switch to it as needed. You can also create new GameObjects with those assigned presets, saving you time.

This dialog will list all of your presets. Click the Save current to and from the Project Browser, select the Presets folder. Call it Kinematic. Now when you click the preset button again, you’ll see your newly saved preset. Presets are a great way to save your current configuration settings when you want to make changes.

The last of the three buttons in the top right-hand corner of the component is a gear icon. Click it. This dialog will appear:

Here are the most important options listed here:

  • Reset will reset the component to its default values.
  • Move to Front and Move to Back adjust the ordering of sprites in 2D games.
  • Remove Component will delete the component from the GameObject — you can undo this action.
  • Copy Component allows you to copy a component from one GameObject and paste it onto another.
  • Paste Component as New will paste a copied component to a GameObject.
  • Paste Component Values allows you to overwrite the values of the current component from a copied component. Specifically, you can copy the values of a component while your game is being played. When you stop the game, you can paste those values onto another component. This is quite useful because sometimes it’s useful to tweak things as you play to see what works in practice.

From the menu, select remove component. Now click the add component button again, and add a Rigidbody component back to the GameObject. Remember, it’s in the Physics category. Finally, click the presets button and select the Kinematic preset.

Notice that the Rigidbody component was auto-magically updated per your preset. But you may be asking, what’s a Rigidbody?

By adding the Rigidbody component to the space marine, you’ve made it so that he now can respond to collision events and respond to gravity. However, you don’t want him bouncing off enemies or walls. You definitely want to know about those collisions events, but you don’t want the hero to fly out of control just because he bumped into a column.

The isKinematic property tells the physics engine that you’re manually controlling the marine, rather than letting the physics engine move the marine for you. But the physics engine is still aware of where the marine is and when it collides with something. This is helpful so that when the marine collides with an alien, the physics engine will notify you so you can make something happen — like the space marine getting chomped!

By unchecking the Use Gravity option, the space marine won’t be affected by gravity. Again — you don’t need this because you’ll be moving the marine manually and are only using the Rigidbody for collision detection.

Now comes the fun part: It’s time to make that marine dance! Or move. That’s fine, too.

Unity provides some built-in components to make movement easy. But for learning purposes, in this tutorial. you’ll do everything manually through the power of scripting.

Introducing Scripting

For the non-programmer, at best, scripting is a small barrier to entry. At worst, scripting is the devil that never sleeps.

Coming from an arts background, I can say that scripting is not as hard as you might imagine. Like anything, it just requires some time and patience to understand how it works.

In this tutorial, you’ll write scripts in C#, which is a popular language developed by Microsoft that works for both mobile and desktop apps. It’s feature-rich and fully versatile. Unfortunately, I can’t teach it all within this tutorial.

Thankfully, you can learn C# at raywenderlich.com where there’s a free course that teaches the language from the ground up, for complete beginners.

It’s designed for non-programmers and taught within the context of Unity.

If you’re a beginner to programming, definitely check that out first. If you’re an experienced developer, or a particularly brave beginner, feel free to continue along, since everything in this tutorial is step-by-step; just understand that there may be some gaps in your understanding without C# knowledge.

Why Not JavaScript?

Back in the day, Unity shipped with Javascript and a python variant called Boo. Most developers used C# so in 2017, support was dropped for Javascript. Boo was dropped a few years earlier. Now, all scripting is done entirely in C#.

You may encounter tutorials that reference Javascript, but you can’t even create Javascript files in the editor anymore. This is a good thing since Unity has since focused on their C# implementation, updating it to a near contemporary version of the language.

C# may take some time to learn, but you can leverage those programming skills outside of Unity. For instance, if you find yourself disliking game development (or having a hard time making a living) but enjoying the language, you can transition those skills into a C# development job, creating desktop or mobile apps, or even developing backend server apps.

The way coding works in Unity is that you create scripts. Scripts are simply another type of component that you attach to GameObjects, that you get to write the code for.

A script derives from a class called MonoBehaviour, and you can override several methods to get notified upon certain events:

  • Update(): This event occurs at every single frame. If your game runs at sixty frames per second, Update() is called sixty times. Needless to say, you don’t want to do any heavy processing in this method.
  • OnEnable(): This is called when a GameObject is enabled and also when an inactive GameObject suddenly reactivates. Typically, you deactivate GameObjects when you don’t need them for a while but will have a need at a later point in time.
  • Start(): This is called once in the script’s lifetime and before Update() is called. It’s a good place to do setup and initalization.
  • Destroy(): This is called right before the object goes to the GameObject afterlife. It’s a good place to do clean up, such as shutting down network connections.

There are many other events that you’ll discover throughout this tutorial. To see a complete listing, head to the MonoBehavior reference on Unity’s site:

Creating Your First Script

It’s showtime!

You have many options for creating a script. You could click the Add Component button and then select New Script.

But I’d like you to try it this way: Select the Scripts folder in the Project Browser, and then click the Create button. Select C# Script from the drop-down menu and name it PlayerController.

You’ll see that your new script in the Scripts folder. Drag it from the Scripts folder onto the SpaceMarine GameObject.

You should now see the script listed as one of the components on the SpaceMarine GameObject in the Hierarchy.

You’ve added your first custom component! Granted, it doesn’t do anything… yet.

You’ll change that in just a moment butm before you do, you need to learn about the Input Manager.

Managing Input

Inputs are the game’s controls, and if you’re developing a game for a desktop computer, your users will expect the ability to rebind keys. Unity’s Input Manager makes this easy, and is the preferred way for your game to deal with user input.

To get access to the Input Manager, click Edit\Project Settings\Input.

The Inspector will look pretty empty. Click the disclosure triangle next to the word Axes.

Once expanded, you’ll see all the pre-configured inputs that are available to you.

The first property is Size, and it’s the number of inputs your game uses. You can decrease the number to decrease the amount, and increase it if you want more inputs. The current amount of inputs is more than enough for this game.

Click the disclosure triangle next to Horizontal. Here you can configure the input for the horizontal axis, i.e., left or right.

Here’s a breakdown of the key fields:

  • Name is the name Unity gives the input. This example is called ‘Horizontal’, but you can call it anything. This is also the name you reference in code, which you’ll see in a moment.
  • Descriptive Name and Negative Name are the names presented to the user in the Unity game launcher if they want to remap the keys. You can disable the Unity game launch and provide your own key mapping interface if you’d like, so these aren’t required properties.+* Negative and Positive Buttons are the actual keys being used. Unity allows buttons to have negative or opposite keys. For instance, the right arrow key is positive while the left arrow key is negative. You don’t need to provide a negative for all keys — it wouldn’t make sense to provide a negative key for a use action.+* Alt Negative and Alt Positive Buttons are alternative keys. In this case, instead of Left and Right Arrow keys, you enable the A and D keys.

The other fields mostly relate to the functionality of analog sticks. For simplicity, this game will only use keyboard input. If you wanted to make the game a bonafide twin stick shooter, these are the options you’d tweak to create a tight control scheme.

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;
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.

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

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.

What do these numbers mean?

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.

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

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.

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!

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:

  1. The Mesh Filter is a component that contains data about your model’s mesh and passes it to a renderer.
  2. The Mesh Renderer displays the mesh. It contains a lot of information about lighting, such as casting and receiving shadows.
  3. 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:

  1. 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. Since Instantiate() returns a type of Object, the result must be cast into a GameObject.
  2. 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.
  3. 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.

Note: If you wanted to check the right mouse button, you’d pass in 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!

Where to Go From Here?

At this point, you should be feeling more comfortable with Unity. You have a walking space marine with a functioning weapon. You’ve learned the following:

  • Components and how they give your GameObjects behavior.
  • Scripting and how to use scripts to create custom behavior.
  • The Input Manager and how to access it from code.
  • The Game window and how to test your games.

This was a thick, heavy series and you made it to the end. Congratulations! You’ve come a long way.

There’s still a lot more to do. Your poor marine is a sitting duck because he can’t turn around to see what’s sneaking up behind him. At the same time, he has nothing to worry about because there are no aliens hordes attacking him — yet!

If you’ve enjoyed this tutorial series and want to learn how to finish off your game (and build more amazing games in Unity), check out the complete Unity Games by Tutorials book!

The book teaches you everything you need to know about building games in Unity, whether you’re a beginner or a more experienced game developer. In the book, you’ll build four great games:

  • A 3D twin-stick shooter
  • A classic 2D platformer
  • A 3D tower-defense game (with virtual reality mode!)
  • A first-person shooter

Check out the trailer for the book here:

If you have questions or comments on this tutorial, please leave them in the discussion below!

Average Rating

5/5

Add a rating for this content

2 ratings

Contributors

Comments