Megabite #2: Creating Your Own Video Game From Scratch (part 2)

In the first installment of Megabite, we covered some of the framework and terminology that makes up Unity3.  These, of course, are simply the boring pieces of framework that make up the foundation of getting yourself started.  (Be sure to start there if you are planning to follow along)

We'll pick up where we left off: a cube and a camera.  When played, the game merely consists of the arrow keys being scripted to manipulate your cube on the most basic of levels.  Next, we're going to accomplish something fun - we're going to make our cube fire bullets that are capable of destroying targets.

First Things First:

In order to make sure we are all on the same page here, we want to position our camera so that the controls make the most sense.  Based on the script we had before, we want to place our camera above the cube and rotate it using the inspector.  What I have (pictured below) is an X rotation of 90 degrees and a y-rotation of 90 degrees as well.  When played, this gives us a view that makes the cube go upward when the up arrow is pressed, and down when the down arrow is pressed.

The positioning and rotation can be altered as you see fit, but the following tutorial will fire a GameObject from the right side of the cube that will move in a negative direction along the Z-axis.

Crafting Your Bullet

This is our universe, so we make the rules.  We don't have to make things aerodynamic, and things don't have to make sense according to our physical world.  If you want your bullet to be the size of a truck, that will be entirely possible.  We will be attributing our own physics and making everything from scratch, including the laws of physics.

To begin, use the "Create" button on the hierarchy to make a shape.  You can choose a cylinder, capsule, cube, or sphere.  The scale of the object will be much more important than the actual shape of it.  Change the Transform Position of the new object at 0,0,0 and scale it to something that makes sense for you.  After that, use the blue Z-axis arrow to move your new object to the right side of your cube.  Because your project might vary slightly from my own, make a note of the z-position of your object when you have moved it far enough away from the cube so that it no longer touches.

 

At this point, we're going to add something new to the bullet - a Rigidbody.  Rigidbodies are GameObjects that our custom physics apply to.  For our purposes, our bullet be able to accept a variable amount of force and fly across the screen at a rate that we choose.  To do this, select Component -> Physics -> Rigidbody from the main menu.

Our world still does not have a "ground" to fall toward, so we want to turn off gravity for the Rigidbody component via the inspector (as pictured).  All else can remain the same.

Pre-Fabulous:

Remember when I mentioned Prefabs in Megabite #1? Well, now this is where they come in handy.  Obviously we're going to want more than a single bullet.  We want the ability to make as many as we want and we also desire for those projectiles to fly across the screen.

Create your very first Prefab by selecting Assets -> Create -> Prefab from the main menu, and you should see a new object appear within your assets.  Name this object "Bullet".  Once that is done, just click and drag your bullet shape from the hierarchy tab and drop it on top of your brand new Prefab.  What this does is essentially create an asset out of a GameObject, and it also gives us a single thing to manipulate that will change every instance of "bullet" we create in the game.

Believe it or not, your next step is to delete your bullet shape from the scene.  After all, we don't want to start the game with a bullet just sitting there, do we?  Right-click your shape in your hierarchy and delete it.  On the next page, we will script the firing mechanism and get that bad boy flying.

Instantiate:

The method we will need to use to create our bullets in-game is called Instantiate.  Despite the difficult-to-say name, the purpose and usage of this integrated function is actually pretty easy.

By creating this script and attaching it to the cube, we do the following:

  • "listen" for the space bar to get pressed
  • Check to see when the last bullet was fired and measure it against our firing delay
  • When it is, the game will create a clone of whatever prefab we attach to the inspector.
  • The clone is placed wherever our cube is, even if we move it.  The only difference is that it will be +/- on the X-axis if we mess with the "spawnDistance" variable we just created.
At this point, we simply need to click on your cube within the Hierarchy and look in the section that regards our new script.  There will be a section that allows you to drag and drop a Prefab onto our "bullet" variable.  Go ahead and drop your bullet Prefab asset.

Play the game to make sure there are no scripting errors and you will see the cloning effect in action.  You will see an issue that is apparent with how everything is scripted though - because we haven't set up a delay, we are basically creating a new object every frame.  The reason for this is because we are using the "Update" function, which executes for every single frame.  If we choose, we can create additional functionality to prevent or further customize this.

A note about Instantiate: this command is extremely powerful.  It is often used to spawn things such as enemies or players as well as anything else that may need to be created as the game runs.  The more creative you are with each new thing you learn, the more capability things will have.  Experimantation is key.  :)

Destroying Your Target:

One more script will be required to complete the effect.  When the bullet is spawned into the game world, we want it to move across the screen and destroy anything it collides with.  Because it will already spawn when we press the spacebar, the script will be pretty simple.

Our bullet Prefab has a Rigidbody component already, and Rigidbodies can respond to forces that we apply.  So, we need a script that will apply a numerical force that will symbolize how much push we are adding to our bullet once it exists.  Remembering that it has a mass of 1 and no gravity to worry about, we won't need to add an extreme amount of power.

Drop this new script onto your bullet Prefab (you can do this within your assets window).

In the first part of the code, you can see that the bullet immediately has force that can be changed via the inspector.  In the second portion, you can see a new function that pertains to the "Collision Collider" of the bullet.  This code executes once the bullet actually connects with any other object that has a collider component. (by default, new shapes and such already have this component attached and there is no need to add one.  In future lessons, we will explore the customization of these components).

"Destroy" is the key unity function at work here.  We are destroying 2 things with each collision: the object we hit and the bullet itself.  Our collision function creates a variable on the fly so that we can manipulate our game in many possible ways.  Another cool addition to the code itself is an integrated delay that Destroy can use by simply adding a comma and an amount of seconds.  For instance, Destroy(collision.gameObject, 3) will wait 3 seconds before the object is destroyed.  The reason I added the  3 to the "Start" portion of the script will be to auto-destroy each fired round after 3 seconds, for example.  This will have a great effect if we actually include Rigidbodies on our targets because physics will apply.  Based on whatever mass we give our targets, we will get different effects.

Before you create targets, be sure your code is functional by playing your game.  Adjust your "force" variable on your bullet Prefab until you get your desired results.  You can also play with your "drag" and "mass" amounts within the Rigidbody component here until you get more specific results.  Drag will apply friction to your bullet and cause it to slow in speed over time while mass will increase the weight of the projectile.  If you increase mass or drag, you'll need to add more force to compensate.

Once you have everything where you want it, simply add some targets to the scene via your Hierarchy.  If you chose to delay the destruction of your GameObjects within the script, you can apply your Rigidbody components now to each target you set up.  Be sure to turn off gravity and adjust the mass of each accordingly if you do so.

Experimentation will lead you to new results.  You can set up objects as virtual pins and remove the Destroy lines from your script to create something similar to bowling.  You can make your targets extremely light in mass and crash into them with an extremely heavy object to achieve a cannon-like effect.

Thanks for following along yet again, and stay tuned for next week where we can look into some even cooler features!