Let’s make Tappy Plane with Unity!
In this article I’m going to show you how to create the Tappy Plane game (similar to Flappy Bird) using Unity!
Here’s what we’re going to be building:
You can get the source code for the game here on GitHub.
What we’ll be using:
- UniRx — for reactive programming and for a nice and clean data and view separation.
- Tappy Plane assets from Kenney.
Adding a repeating background and ground
We begin by creating the background that we’ll be using in the game. The sprite is for the background is Assets/Sprites/background.png
.
Making the repeating images
The RepeatingBackground
component is attached to a component Background
which contains all the segments of the background as child game objects. We first initialize all the segments of the repeating background into a queue in the order they appear in the scene. The segments are just the same image joined together and moving towards the left of the screen at a certain speed. When the first segment leaves the screen completely we send it to the back of the queue (to become the new last segment) and move its position to be the right-most segment in the screen — but still joined to the other segments. We keep doing this until the game stops. By doing this we create the illusion of a never-ending background.
Here’s what’s actually happening in the scene:
This works because of the way the sprite was designed.
We do the same for the ground, but with a faster speed since it is in the foreground (the sprite is Assets/Sprites/groundGrass.png
)
Creating the plane
We’ll be using these sprites for the plane:
We select the three at once and drag them onto the scene. This opens a dialog that allows us to create a new sprite animation automatically. Now we have the plane in the game with rotating blades:
Detecting player input
In Plane
script component, we get input from the player to make the plane jump. When the user clicks the left mouse button or presses the spacebar key we set the velocity in the Y direction. This is the initial velocity the plane has before losing speed due to gravity (we attached a Rigidbody 2D
component to the plane to enable physics). The game will end when the player collides with an obstacle, so we stop detecting input when that happens and the plane falls to the ground.
Creating obstacles
We use these two sprites to create the obstacles:
We make them move together by making them both children of the same parent Rock Grass
in the Hierarchy
window.
We have a GameController
game object (to implement the singleton game manager pattern) in the scene. It has a GameController
script attached to it which has firstRockPair
serialized field. We set this field to Rock Grass
in the Unity Editor. Rock Grass
is the first obstacle the player will encounter in the game and is the object we’ll be cloning to create more obstacles.
When the game starts we create a clone of firstRockPair
and place it a random distance away from firstRockPair
. After a random number of seconds at which point the first clone has moved to the left considerably, we create another clone of firstRockPair
.
Detecting collisions
We attach a Polygon Collider 2D
component to the plane and to the two children of Rock Grass
that show the top and bottom rock sprites (rockGrass
and rockGrassDown
) to enable collision detection that we handle in the Plane
script:
At this point we already have a fully functional Tappy Plane game!
Adding scoring
We create an invisible game object in the scene and make it a child of Rock Grass. We tag this object as ScoreIncreaseTrigger
. We place it in the scene just behind the rock pair, so that when the OnTriggerExit2D
function is called for a trigger collision between the plane and this object, it would mean that the plane has successfully passed through the rock pair and so we increase the players score.
The score indicator
Instead of a font to show the player’s current score, we’ll be using these sprites (one sprite for each digit of the score):
So we need a custom method to update the sprites shown according to the score from the Score
component.
We store Image
s for each digit in a list. These images are place side by side in the scene. So let’s say the current score is 9. 9 has only 1 digit, that means we have only one image in the list. What happens when we update the score to 10? Well, 10 has 2 digits (1 and 0) so we update the sprite of the first image in our list to the sprite showing number 1. Then we create a new image in the list and set it’s sprite to the sprite that displays the number 0.
Adding stars
We spawn a new group of stars after the plane passes through a random number of rocks since the last time a star group was spawned.
SpawnStars()
makes the stars in each star group take the path of semi-circle. Each of the stars in a group is rotated around the same point with an angle based on their position in the group.
When the plane hits a star, we destroy the game object of the star and increment the star count:
The last thing we need to do is to add a star count indicator. The StarCount
component simply detects changes in the number of stars and updates the text of the indicator in the scene accordingly. We used a font (KenVector Future) this time around so we won’t be using a custom update method like we did for the score indicator. We just need set the text
property.
And that’s it! We have Tappy Plane up and running (flying, jumping?)!
We could add more features to the game. The assets from Kenney contain sprites that we could use to create things like an exhaust animation, when the plane jumps. We could even change the weather using the various variations of the ground and rock sprites.
You can find the project here on GitHub. Maybe you could clone it and have a go at expanding it yourself? Or start from scratch if you like?
Anyway, I hope you had a great time reading this article and now you know how to make a game with mechanics similar to this.