Session 2

Shooter game continued

Making targets to shoot

Now we need to make objects for your ship’s bullets to hit. Go to the Create Menu in the Hierarchy Window, highlight 3D Object and click on Cube. In the Inspector, name the cube GameObject “Enemy”. If you’d like, you can modify the rotation in the Transform to look more interesting in your camera view.

If you hit play and start shooting now, you’ll notice that the bullets fly through the new enemy.  We need to add some components and code to make the bullet and enemy interact.

First, we need to add a Rigidbody Component to the enemy. The primary purpose of Rigidbody is to add physics to objects, but it’s also how Unity tracks collisions. With the Enemy GameObject selected, click on Add Component, then Physics, and click on Rigidbody. For this game, we’re only interested in the collision, and not the physics, so we’re going to turn them off. Click the checkbox next to “Is Kinematic.” This option will freeze the enemy in place and ensure that it will only move when we tell it to with scripting.

Now we need to categorize the enemy so that we can easily track collisions related to it in our scripts. At the top of the Inspector panel, right below the Enemy name, is the Tag dropdown menu. Click this menu and then click “Add Tag…” to open the Tags & Layers panel. Under the Tags list, click the small plus (+) sign at the bottom of the list to add a row. Type “enemy” in the row you just created. Click on the enemy in the hierarchy again.

Just like we made our bullet prefab, we can make our enemy a prefab, by dragging the Enemy from the Hierarchy Window to the Project Window. Instead of attaching this prefab to a script like the bullet, we can add the Enemy directly from the project, and each version will have the correct settings without having to make one each time. Now you can place multiple Enemy objects into the Scene as you like. Rows like Space Invaders? Different patterns? You decide!

Now that our enemy is set up, we need to create the behavior during a collision. Remember when we ticked “is Trigger” on the Collider component for our Bullet Prefab before? That’s going to be important now. We can track the collision either by setting up a script on the enemy and looking for the bullet, but we already have a script on the bullet, so let’s add code to that to make things easier.

Destroying Objects

Now we’re going to add code to our Bullet.cs script that will detect when the bullet hits the enemy. The bullet is set as a “trigger”, and when it collides with the enemy that has a Rigidbody on it, Unity will register that as a trigger event. We can track those events and perform behavior in reaction to it by using the OnTriggerEvent function.  Let’s add the following code to the Bullet.cs file in our code editor:

void Update () {
    transform.Translate(0, 10 * Time.deltaTime, 0);
}

void OnTriggerEnter (Collider other) {
  if (other.CompareTag("enemy")) {
    Destroy(other.gameObject);
    Destroy(this.gameObject);
  }
}

The core of this new code is straight forward. In the first highlighted line, we’re identifying the name of the function, so Unity will execute it when it registers the trigger event. “Collider other” is giving a temporary name to the object that’s being touched. “col” or more descriptive names are also common.

In the second line, we’re declaring that this is conditional. The code within the curly brackets { } will only execute if the condition within the parantheses ( ) is true. In this case, we only want to destroy objects tagged “enemy”. Right now, we only have enemies in our scene, but we could add barriers or asteroids that could block bullets, and we will need different behavior for those objects. If this bullet touches something that is not an enemy, it will ignore it and pass right through it.

Within the brackets, we’re doing two things. Destroying the object we’re hitting — the enemy — and destroying the object this script is attached to — the bullet. If you want the bullet to be more powerful, you could omit the line destroying the bullet. The bullet would then mow down rows of enemies. Or you could create a special bullet that has that property.

Press play, and try shooting the enemies you placed in the scene. You should see them disappear when the bullet hits them!

Cleaning up

Now is the time for some cleanup.  So far, if our bullets don’t hit anything, they fly off into space forever. Every time your ship shoots a bullet, it adds to the game world, and Unity has to keep track of each one of those. In a simple game on a modern computer, this may not be a noticeable problem, but this could slow down the game. We want to make sure we’re efficient and tidying up after ourselves.

For the bullet, we don’t need to keep track of it after it has gone past the top of the screen and we can’t see it anymore.  We can use a Conditional If/Else statement to perform certain behavior while a condition is true, and perform different behavior when it is false.

We want to keep moving the bullet up until it is well off the screen, and when it is outside of that boundry, we’ll destroy it. In the If code below, the bullet will move up as long as the current y coordinate is less than 15. When the bullet goes past that point, the condition will become false, and the code under Else will execute, in this case, destroying the bullet.

void Update () {
  if(transform.position.y < 15.0f) {
    transform.Translate(0, 10 * Time.deltaTime, 0);
  } else {
    Destroy(this.gameObject);
  }
}

 

Give your objects some color

So far, we’ve been creating basic primitive 3D shapes with the default color and material on them. We can make objects more distinct by creating Materials and applying them to our GameObjects.

In the Project Window, open the Create Menu and click on Material. This will create a Material file in your project’s folder, and the name will be highlighted so you can rename it. Let’s name this first Material “Ship” and press the enter key. In the Inspector window for the Material, there are a couple of settings that we are interested in. Leave Shader and Rendering Mode at Standard and Opaque. Albedo determines the surface color of the Material. I have used a medium grey, but you can use any color here.  I’d like to make the ship look metallic, so I’m going to adjust the Metallic slider up to 0.5, and move the Smoothness slider to .75. The easiest way to apply this Material to the ship is to select the Material in the Project window, and drag it on top of your ship, either in the Scene window, or in the Hierarchy.

I’d like the bullet to look more like a laser blast, so I create a material with a bright color, such as light blue, and set the Emission to 1, so that is glows brightly. Add this new material to your bullet prefab by dragging it on top of the prefab in the Project Window.

I’d like the bullet to have a glow that also affects other objects, so let’s add a light component on the by clicking on the Bullet Prefab in the Project Window, clicking Add Component, Rendering, and then Light. By default, the light should be a point light, which is what we want. Now change the light intensity up to 1, and change the color to match the color for the emission of the material.  When you go into Play mode and shoot bullets, they will light up enemies as they go past.