Tutorial: How to Make Flappy Bird in Unity3D
Yes, using a 3D game engine for a 2D game.
This is a tutorial that will teach you how to make a clone of Flappy Bird called Tappy Plane using Unity3D. You should use this tutorial if you’re a beginner to Unity 2D game development with some C# programming experience. Let’s get started!
Install Unity
Unity3D is a free game development engine. Although Unity3D has “3D” in it, its most recent version supports the creation of 2D games. When you create a game on Unity, it can be run on iOS, Android, Windows Phone, the Web, and many other platforms.
Create a new project
When you open up Unity, this should be the first window you see.
Go to the Create New Project tab and select the folder to put it in. The name can be changed later. Change the setup defaults for at the bottom to be 2D. Then press the Create button.
Organize your project
After creating the project, you should be greeted with this blank screen.
Navigate over to the Project window at the bottom to create the folder structure you need to organize your files. Add four folders called “Prefabs”, “Scenes”, “Scripts”, and “Textures”.
Here’s an explanation for what type of file each folder holds.
Prefabs
In Unity, a Prefab is an object that can be reused and created such as bullets, enemies, or walls.
Scenes
A scene is like a level of a game.
Scripts
This folder will hold all the code.
Textures
All the images used in the game. In 2D gaming, these images are called “Sprites”.
Set up the background
Save this image to the
Textures
folder you created.![]() |
ADD TO TEXTURES FOLDER |
Drag the image into the center main Scene area. Using the inspector, set the scale to be
2.5
in both the X and Y fields.Add the player
Save this image to the
Textures
folder. Drag and drop it into the scene just as you did with the background.
Set the value of Z in the right side bar under Transform to
-1
. This ensures that the player will always be in the front.
In the inspector, click Add Component, type “Rigidbody 2D”, and press enter. A Rigidbody component gives the airplane gravity and other physics characteristics.
Press the triangle Play button at the top of the screen. You should see the plane falling as it adheres to gravity.
Controlling the Player
Now we’re going to create a script that allows the player to move. Inside the Scripts folder, create a C# file called
Player.cs
. Fill the contents with this code:using UnityEngine; using System.Collections; using UnityEngine.UI; public class Player : MonoBehaviour { public Vector2 jumpForce = new Vector2 (0,300); Rigidbody2D myPlayer; public Text scoreText; private float startTime; // Use this for initialization void Start () { myPlayer = GetComponent<Rigidbody2D> (); startTime = Time.time; } // Update is called once per frame void Update () { if (Input.GetKeyUp("space")) { //for mobile Input.touchCount>0 && Input.GetTouch(0).phase==TouchPhase.Ended; myPlayer.velocity = Vector2.zero; myPlayer.AddForce (jumpForce); } //Die by being OffMeshLink screen Vector2 screenPosition=Camera.main.WorldToScreenPoint(transform.position); if (screenPosition.y > Screen.height || screenPosition.y < 0) { Die (); } scoreText.text = (Time.time - startTime).ToString("0.0"); } void OnCollisionEnter2D(Collision2D other){ Die (); } void Die(){ Application.LoadLevel (Application.loadedLevel); } }There are two main parts in this code: thejumpForce
variable and theUpdate
method.
jumpForce
stores the force applied to the player when we jump.- It is of the
Vector2
type, meaning that it stores two values:x
andy
. - Because this variable is public, you can change its value in the Inspector.
- It is of the
- The
Update
method is a function that is called every frame of the game. In it, if the spacebar button is pressed, a force is added to the rigidbody.
Add this script to the Player object the same way you added the RigidBody 2D, with the Add Component button. Now when you press Play, you’ll be able to jump up and fall back down.
Creating the obstacles
Drag these two images in and once again, save them into the
Textures
folder. Drag these images onto the Scene and in the Inspector, change their X and Yscales to be 2.5
.
Position these objects so that they are above each other, to the right of the background, and wide enough apart that the player can jump through them.
In the file menu, go to GameObject->Create Empty. This will add an object to the scene that is invisible and will serve as a folder that holds our rock obstacles. Name it “RockPair”. Drag the two rock GameObjects onto the RockPair object.
Moving the obstacles
Add a “RigidBody 2D” component to the RockPair parent object. In the inspector, check Is Kinematic. This prevents the obstacles from being affected by gravity.
Create another script called
Obstacle.cs
and place it in the Scripts
folder. This script will be used to move the rocks from the right of the screen to the left. Fill this file with this code:
:
using UnityEngine;
using System.Collections;
public class Obstacle : MonoBehaviour {
public Vector2 velocity=new Vector2(-4,0);
public float range=1f;
Rigidbody2D rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody2D> ();
rb.velocity = velocity;
transform.position = new Vector3 (transform.position.x+range*Random.value,transform.position.y-range*Random.value,transform.position.z);
}
// Update is called once per frame
void Update () {
}
}
TheStart
method runs once, when the GameObject is created. In this case, we are setting the object’s velocity to be-4
in thex
direction.Add this script to the RockPair GameObject and hit the Play button. You should see the obstacles move across the screen.Generating obstacles
We need to create new rock obstacles every few seconds. To begin, drag the RockPair Object into thePrefabs
folder. This turns RockPair into a Prefab, which is an object that can be created and destroyed many times. Delete the RockPair object that is in the scene.
Create another Empty GameObject and rename it to “Scripts”. Create another Script calledGenerate.cs
. Paste this code into it and add the Generate script to the Scripts empty GameObject.using UnityEngine; using System.Collections; public class Generate : MonoBehaviour { public GameObject rocks; int score = 0; // Use this for initialization void Start () { InvokeRepeating ("createObstacles",0.3f,3.5f); } void onGUI(){ GUI.color = Color.black; GUILayout.Label(" Score: " + score.ToString()); } void createObstacles(){ Instantiate (rocks); } // Update is called once per frame void Update () { } }
In this script, we use theInvokeRepeating
method. This will call a specific function once every several seconds. The first parameter is a string with the name of the method to call. The second is the number of seconds to delay these repeated calls. And the third parameter is the number of seconds between method calls.
In theCreateObstacle
method, we useInstantiate
, a method that will generate a new prefab to the scene. And the prefab that we add to the scene is a variable calledrocks
. This variable isn’t linked to our RockPair prefab yet though. To do this, drag the RockPair prefab from its folder into the empty field that says rocks in the Inspector.Follow this video(.gif):
Try running the code. You should see obstacles being generated every 1.5 seconds!Killing the Player
You may have noticed that running into the obstacles doesn’t do anything. Let’s make something happen because of this collision.Click on the player GameObject. Add a component called “Box Collider 2D”.Now go to the RockPair prefab and click on the small arrow. Select the first object and add a component called “Polygon Collider 2D”. Do the same for the other Obstacle.A Collider component is a shape that triggers collisions to happen. Play the game and see what happens. It’s a really interesting thing to watch.When the player collides with the obstacle, let’s make the game restart. We’re going to edit thePlayer.cs
file to do this. Open the file up and edit it to look like this:using UnityEngine; using System.Collections; using UnityEngine.UI; public class Player : MonoBehaviour { public Vector2 jumpForce = new Vector2 (0,300); Rigidbody2D myPlayer; public Text scoreText; private float startTime; // Use this for initialization void Start () { myPlayer = GetComponent<Rigidbody2D> (); startTime = Time.time; } // Update is called once per frame void Update () { if (Input.GetKeyUp("space")) { //for mobile Input.touchCount>0 && Input.GetTouch(0).phase==TouchPhase.Ended; myPlayer.velocity = Vector2.zero; myPlayer.AddForce (jumpForce); } //Die by being OffMeshLink screen Vector2 screenPosition=Camera.main.WorldToScreenPoint(transform.position); if (screenPosition.y > Screen.height || screenPosition.y < 0) { Die (); } scoreText.text = (Time.time - startTime).ToString("0.0"); } void OnCollisionEnter2D(Collision2D other){ Die (); } void Die(){ Application.LoadLevel (Application.loadedLevel); } }
- Inside the
Update
method, we’ve added some lines of code that check if the player’s position is inside the screen or not. If it’s not, the player will die.transform
holds the position, rotation, and scale of whatever GameObject the script is attached to.
- The
Die
method will cause the level to reset. - The
OnCollisionEnter2D
method is called whenever there is a collision detected between two GameObjects that have Collider 2D components.
Run the game. The game should restart every time the player crashes or goes off screen.
Add a touch of randomness
If you try to play the game now, it can be a little… boring. We need to vary the height of the rocks to make it more challenging.Update your Obstacle.cs
file.
using UnityEngine; using System.Collections; public class Obstacle : MonoBehaviour { public Vector2 velocity=new Vector2(-4,0); public float range=1f; Rigidbody2D rb; // Use this for initialization void Start () { rb = GetComponent (); rb.velocity = velocity; transform.position = new Vector3 (transform.position.x+range*Random.value,transform.position.y-range*Random.value,transform.position.z); } // Update is called once per frame void Update () { } }
- The
range
variable is a range of randomness. The higher this number is, the greater the variation the rocks will be. You may need to adjust this value to fit your game.- When the object is first created, we move its position down a random amount.
Keeping score
Finally, let’s keep score. Update theGenerate.cs
file to look like this:using UnityEngine; using System.Collections; public class Generate : MonoBehaviour { public GameObject rocks; int score = 0; // Use this for initialization void Start () { InvokeRepeating ("createObstacles",0.3f,3.5f); } void onGUI(){ GUI.color = Color.black; GUILayout.Label(" Score: " + score.ToString()); } void createObstacles(){ Instantiate (rocks); } // Update is called once per frame void Update () { } }
- We now have an integer used to keep the
score
- The
OnGUI
method is called several times a frame and is used for displaying text and buttons. Here we display the score in the top left of the screen in black text. - Every time a new obstacle is created, a point is added.
Save your work
Go to File->Save and save this level into the
Scenes
folder, named Play.unity
. Breathe a sigh of contentment.That’s all folks!
Congratulations! You’ve made a Flappy Bird clone in Unity. Feel free to change this game and work on your own ideas and art. Here are a couple ideas on things to change:
- Right now, we create new obstacles, but never destroy them. After a while of running, the game could slow down a lot.
- There is no proper menu or play screen.
Thanks for reading! If you enjoyed this please share, and if you have any questions, feel free to ask me.
Mobile gaming and development is definitely a huge market which can be used for potential revenue. There are so many success stories for games such as Clash of Clans, Candy Crush, Angry Birds. These games have managed to inspire a million others to take some initiative in the world of iOS and Android game development. About 62% of mobile users install a particular game just a week after they buy their device.
ReplyDeleteVarious latest technologies such as AR and VR are integrated in the game development for mobile to give a better experience and take the gaming level to a whole new level. From 2D game development to 2D advanced games, technologies have drastically changed. Previously, game development for Android came into existence as iOS had limitations. But today’s era has changed. There are thousands of games in the industry, both for Android and iOS users.
ReplyDeleteCASINO HOTEL CASINO & HOTEL NEW JUNIOR LAKE
ReplyDeleteBook CASINO HOTEL & HOTEL in 원주 출장마사지 New London 평택 출장마사지 - 경상남도 출장마사지 JTM Hub 구미 출장샵 offers the best Hotel deals on your next trip. 강릉 출장샵 Book the hotel with JTM Hub today.