I do Technical Evangelism stuff at Microsoft Greece. Please visit new and updated blog at www.dgkanatsios.com
Please check the new and updated blog at http://www.dgkanatsios.com
Current blog post can be found at http://dgkanatsios.com/2014/07/02/a-flappy-bird-clone-in-unity-source-code-included-3/
Unless you’ve been living in a cave or visiting outer space, you have certainly played Flappy Bird, one of the most successful games for mobile devices. Hence, I decided to give it a shot and recreate it using Unity. Needless to mention that all graphics and sounds found in the tutorial are used only for educational purposes and do not intend to harm any intellectual property at all circumstances. The sprite sheet used was found here http://www.spriters-resource.com/mobile/flappybird/sheet/59894/ whereas the sounds were extracted from this youtube video https://www.youtube.com/watch?v=xY0sZUJWwA8
Game code was written in Visual Studio (check the free Community edition here). For debugging purposes, don't forget to check the Visual Studio tools for Unity here.
So, let’s start with the small tutorial! This game’s development has many aspects, we’ll attempt to touch all of them one by one. First of all, we used Unity’s spritesheet editor to “slice” the spritesheet and get references to specific sprites
Then, we created a small animation to simulate the flight course of the bird (this can be easily accomplished if you drag-drop the relevant sprites into the scene).
Now, let’s take a more detailed look at our scene. We have various objects made children of our perspective camera and the Flappy bird.
The Background is a Sprite GameObject which has a RandomBackgroundScript attached. We provide the two backgrounds from our spritesheet as parameters.
The Ceiling (not visible during the game!) is a simple quad equipped with a BoxCollider2D component that basically prevents our bird from leaving our gameplay screen.
The Score is a GameObject that holds a reference to the ScoreManagerScript which contains score-handling code. The Script is provided the sprites for our numbers. It starts with a single sprite enabled (Units) and two other Sprites disabled, specifically Tens and Hundreds, which are activated when the player’s score is larger than 10 and 100, respectively. It also stores reference to our sprite digits.
In order to save performance, the sprite/score calculation is achieved if and only if the score has changed from the previous update call. Then, the respective sprites are enabled and the relevant score is shown.
The IntroGUI GameObject shows the sprites of the start screen whereas the DeathGUI (which is disabled at the start of the game) shows the sprites of the death screen.
Let’s check the PipeColunnPrefab, which is identical to the PipeColumnPrefab2 with some sprite differences. The prefab is made by two sprites that are kinematic rigidbodies and a triggered BoxCollider2D. Both are tagged as “Pipe”. Plus, between the two pipes there is an empy GameObject with another BoxCollider2D, which is tagged as “pipeblank”. One can easily make out that when the bird hits the pipes, the player will lose whereas when it hits the “pipeblank” the score will increase by 1.
The Camera has a CameraFollow script attached that gets a reference to the Flappy bird transform. The Update script allows the Camera to update its position based on the bird’s position, slightly moved to the left. It’s customary for infinite runner games to have the camera not in the center but a bit left, in order to have more space on the right so that the player encounters incoming obstacles/blanks/whatever early enough (in our case, the pipes).
The Floor GameObject holds 2 sprites of the floor, has a BoxCollider 2D and a FloorMove script and is tagged as “Floor”. When the first floor moves too much to the left, the script makes the object move to the right, to simulate that the bird is moving to the right. You may notice while playing that the “fix” of the floor movement is somewhat clumsy. One could work that one out with the –3.9f value modification. For a better solution, I attempted to utilize mainTextureOffset for smoother scrolling, but it is not supported by the SpriteRenderer. This would require to have the floor sprite in another file, import it in Unity as a Texture and set the mainTextureOffset. This can be done but I felt that it was too much for the purposes of the tutorial. If you have a better solution, sound off in the comments section!
The SpawnerObject GameObject has the SpawnerScript which in turn has the duty of spawning the pipe prefabs. We provide the two prefabs as parameters plus a minimum and maximum time for the spawn. Let’s check the code!
First, we randomly select the prefab that we’ll continuously instantiate throughout our game. Then, we use the Spawn method which checks for the game state (more on that later). If we are in the playing state, we Instantiate a new pipe, on a random point at the y axis (to simulate the pipes’ height being differently set) and then we call the Spawn method at a later random time (via use of the Invoke method). Easy enough?
The PipeDestroyer GameObject does the job of destroying (and thus, saving performance and memory) the pipes that our bird surpasses. The script code destroys the parent of the Pipe or Pipeblank, i.e. the entire prefab.
Before we dive in to the Flappy script, let’s take a look at the self-documented code of the GameState class
The Flappy Bird is a Rigidbody2D, has a pretty basic Circle Collider and passes some parameters to the Flappy Script.
Onto the biggest script of our Game, the FlappyScript!
In order to move our Bird to the right, we use this method
On the released game, one thing to notice is that during gameplay, the bird begins to look downwards as it falls and looks up when jumping. Consequently, the bird has two states, one going up and one going down.
We use the below method to make sure that the Flappy bird always has the proper rotation on the z axis.
[Self note: this thread might contain a better solutuon => http://forum.unity3d.com/threads/transform-lookat-or-quaternion-lookrotation-on-1-axis-only.36377/]
While on the playing state, we give a boost on the bird each time the user clicks on taps the screen.
We use this method to get if the user touched or clicked, FYI we could also use Input.GetButtonDown(“Fire1”) that works for both touch and mouse.
On the FixedUpdate method, we give the bird a bit of a boost on the Y axis each time the bird starts to drop(to simulate up and down movement). This is accomplished in this way (even though as I’m writing this I’m quite sure that a Sin position transformation could work).
Floor is a non-trigger collider so we use the OnCollision2D method that sets the game as over
whereas our pipes prefab is made of trigger colliders, thus we use the OnTriggerEnter2D method
The Flappy dies method sets the proper game state, activates the DeathGUI and plays the death sound
Last but not least, we’ll see the Update method!
Thanks for reading! I promised the source code, so here it is! Check the project on GitHub https://github.com/dgkanatsios/FlappyBirdClone
You can play the completed game here http://unitysamples.azurewebsites.net/flappybirdclone.html
For instructions on how to deploy your existing game onto Windows Store/Phone, check out the Microsoft Virtual Academy video here: http://www.microsoftvirtualacademy.com/training-courses/porting-unity-games-to-windows-store-and-windows-phone
its great thanks man!
Good article, but the code you posted in onedrive is incomplete.
Did you open the scene and try to play the game? Works ok for me
Yes, I tried. bird goes up and not responding to my clicks.
Just tested on the latest version of Unity (4.5.2) and it works OK. Can you play the game listed here? unitysamples.azurewebsites.net/flappybirdclone.html It's the same code exactly.
Thanks for response. I just updated my unity and it worked.
You can post the game on the play store and be the next million dollar(though it can work as pocket money for you) but why have you not done so.Does any legal issues arise from that?
Your tutorial very helpful for learning. But I have some problem on game over screen that hot to show high scrore, game score and medals in the game over screen. Please guide me.
Hello, I have a problem with the generation of pipes. While the pipes are appearing in the scene window when the game is running on the play window they do not appear. However the score and death functions when the player collides with them.
Check their z-index or if they are set on the proper sorting layer. I would pause the game in the editor, go into 3D mode, rotate the view to see what's going on.
That was the problem indeed but when I change the camera's z spawner creates them on the same z as the camera , should I remove spawner from the camera item?
Don't mind the last comment I where changing the z on the entire item. Thanks a lot now the appear correctly :)
Hi.. Before I get into this, will I be able to change the graphic references and put my own sprites and objects into the game..
yup, you have the source code so you can do anything with it
hi, thanks for the awesome tutorial
just want to point out that in your github project, the sprites is missing
Powered by Zimbra