Starting To Feel Like a Real Game
A quick recap of what we have done so far. From a day one prototype to a functional game.
Now that we have added a few art assets, and core functionality to our game, everything is starting to come together. This is really starting to feel like a game that people will enjoy mastering.
Recap
Simple Player Movement in Unity 2D
We started by giving ourselves control of the player by setting our WSAD and arrow keys to translate the transform of our player based on input.
Variables: The Building Blocks of Programming
I then discussed the necessity of variables in programming. Everything in your game is going to need variables to exist and interact with any other elements in your game. These are the building blocks of programming. Everything from health, to ammo, to inventory, to score and equipment, these are all controlled by variables.
Pseudo Code: Why?
In this article I went over pseudo code. What it is, why it is useful and when should you use it. This is the act of writing your code in plain english. Either as a note to yourself for what you are trying to accomplish, or if it is not clear what the function is doing at a quick glance. This is also useful to clarify certain functions for your dev team, for the same reasons. By add “//” to the beginning of any line, the following text will be ignored by the program. This can also help if you have code written that is not ready for testing or has not been implemented yet.
Instantiating & Destroying GameObjects in Unity
In this article I added the enemy spawn routine as well as firing lasers using the Space Bar. Enemies are instantiated at random x coordinates, with the y coordinate fixed so they appear at the top of the screen. They then descend downward at a fixed speed and are respawned if they reach the bottom of the screen without being destroyed.
The lasers are done similarly the enemy spawn routine. Only this time the laser is instantiated at the player location and travels up at a slightly higher speed. When reaching the top of the screen, the laser is then destroyed instead of being reused like the enemies.
Creating a Cooldown System
Before this point the laser will fire as fast as you can press the Space key. Here I show one way we can control the rate of fire by implementing a cooldown system. First, we added a few variables to the existing script for our laser behavior.
Using these variables we can now control how fast the player can shoot. If the Space is pressed again before the wait time is resolved the button will not fire a laser. In my code the lasers will fire continuously while the Space is held. This is still controlled by the same variables limiting the speed at which lasers are instantiated.
Introduction to Physics in Unity:
This is where we add some physics to the objects in our game. We add collision to the objects with Collider2D components and give the enemies a Rigidbody2D component as well. At least one of the objects in a collision needs to have a rigidbody component. Since the enemy needs to behave differently if it collides with a player or a laser, it makes sense for the enemy to have this component.
OnCollisionEnter Vs. OnTriggerEnter — When to use them?
This article ellaborates a little deeper on OnCollisionEnter and OnTriggerEnter. It explains which to use in different situations. In the example, I am using OnTriggerEnter2D. Which triggers an action when a collision is detected between the two objects. The objects are able to pass through each other instead of bouncing of each other. In this case the objects are destroyed as part of the collision.
Script Communication in Unity: Using GetComponent
This is where I talk about script communication. In order for one object to interact with another object you need to communicate with the other objects script. Here we do this using GetComponent. First, we establish “damage” as a method that reduces the number of lives the player has remaining. This is done in the player script, where our lives are tracked. Our player starts with three lives. When the damage method is called, we reduce the number of lives by one until zero lives remain and the player is destroyed.
Now we need to use the GetComponent command to access the player script when the enemy object collides with the player object. This example uses the tag “Player” as an indicator as to what object the enemy is colliding with. There is a different outcome if the tag is “laser” instead. If the object the enemy collides with is labeled with the tag “Player” then we will access the player script and run the Damage method within.
Within the SpawnManager script there is a method that is triggered when player lives equals zero. This method tells the SpawnManager to stop instantiating enemies when the player is destroyed. Instead of accessing the SpawnManager script every time the player takes damage, I have the player script GetComponent to communicate in the void start method. This allows the communication to be accessed whenever it is needed instead of using GetComponent every time the Damage method is called. This can save the resources used to GetComponent which can cause your game to slow down if not used efficiently.
Coroutines with Unity!
This is where I introduce you to coroutines, specifically IEnumerators. It’s a bit more complicated than any of the previous methods. If you want a full walkthrough of writing and utilizing the code, see my other article on Coroutines with Unity! I use an IEnumerator in my SpawnManager to continuously spawn my enemies at set intervals. When OnPlayerDeath is called, the SpawnManager stops spawning enemies. This is done using a while loop. In pseudocode it says, while the player is alive spawn enemies, when the player is dead stop spawning enemies.
Containers: Keep It Tidy!
When the game is running and enemies are spawning, the hierarchy window can start to get a bit crowded and flooded with enemies. We use a container for the enemies to spawn into. This is shown in the hierarchy window as container name with a drop-down menu that can be collapsed to see more of the hierarchy window. To see how to make this work, read my article Containers: Keep It Tidy!
From Prototype to Work of Art
After replacing the primitive shapes that were serving as placeholders for the game objects with some 2D sprites and giving the game a background, we turn our prototype into a work of art. With core functionality and a few art assets, this is starting to feel like a real game.
Benefits of Prototyping Without Assets
My last article discusses the benefits of prototyping without assets. This one touches on the time it takes to create assets as well as the cost. By using primitive shapes as placeholders, the developers can focus on making a game that works instead of trying to work around existing elements. This allows the developers to have a little more creative freedom. Focusing more on the functionality than the aesthetics, the core of any good game. If an idea or project is scrapped, you will save a lot of time and money by not spending them on assets that are no longer needed.
My next article will cover Animating Sprites in Unity. I will show you how simple Unity makes it for us to add some animation sequences to our game.