Creating 2D platformer game in Unity3D
Hello! My name is Wojciech Bilicki and I am frontend developer in OKE Software. I specialize in ReactJS and web development. Last year I picked up a new hobby: game development. I fell in love with Unity3d. Currently I am hosting a workshop where I teach people how to write games in C# using Unity3D. Therefore I decided to write and article showing you how can you start with your own 2D platformer game in Unity :).
First off you need to have Unity3D and IDE of your choice installed. Go to: https://unity3d.com/get-unity/download and click
Download Unity Hub.
Once that’s done. You need to use Unity Hub to download Unity Editor itself:
When choosing the Unity version to install I would stick with LTS (Long Term Support) for now.
After the installation we can finally start working on our platformer game. One thing that we’ll definitely need will be some 2D assets to build our world. You can find many free assets pack on the internet. Good places to search are for example:
Top game assets
Find game assets like [Music Assets] FREE Music Loop Bundle, Sprout Lands - Asset Pack, Kenney Game Assets All-in-1…
WARNING: Taking art from OpenGameArt.org to be sold as NFTs? You may be committing FRAUD. Visit this link for legal…
Yet definitely the best place to look for assets when it comes to Unity is:
Unity Asset Store - The Best Assets for Game Making
Discover the best assets for game making. Choose from our massive catalog of 2D, 3D models, SDKs, templates, and tools…
So go ahead and create your account there:
You can use the same account inside Unity Hub:
Going back to Unity Asset Store you can choose
2D and then on the left side filter by the pricing. Select
Free Assets and you should see
Free Platform Game Assets
Next step is to actually adding selected assets to your asset library:
Now we should be set up to actually start working on our platformer game. So go ahead and start new Unity project with 2d preset.
First thing we have to do is to actually import the
Free Platform Game Assets. So in the top tool bar go to:
Window -> Package Manager
from there look to the left upper corner and you’ll find a drop down:
Click on it and choose
My Assets. If you did not sign in previously (in Unity Hub) you’re gonna be asked to do it right now. After that you should see a list of all of your assets from Asset Sto re ready to import into project. You should see
Free Platform Game Assets your assets list:
Download and once it’s done
Project window you should see new folder with imported assets. The folder will be named
Bayat Games and will contain all assets from the package:
To keep our project organized we will create separate folder in which we’ll hold stuff related to our game. I named it
That is the end of our setup. We can finally start adding elements to our scene. We’ll need to things player character that we can control and a floor for him to walk on. Let’s start with the floor.
In platformer games it is common to build the environment using tiles. You can think of them as reusable blocks that player can interact and collide with. If you’ll think of Mario game you can see that whole world is built from these reusable blocks:
We definitely want to do the same. In your project window if you’ll go to:
BayatGames -> Free Platform Game Assets -> Tiles -> Spring -> 256x256
you’ll find a tileset we’ll use to create our world.
Now we make sure that our tiles are properly configured before we start using them in our scene. So Shift-Click all the tiles in the
256x256 folder and you should see the inspector panel pop up on the right side of the editor. First thing we need to do is to adjust the size of our tiles. We already now that their dimensions are 256px for both width and height. Make sure that
Pixels Per Unit value in the inspector is set to that value exactly:
Remember to hit
Apply after you adjust settings.
I copied all the sprites to
PlatformerGame -> Tiles folder just to keep things clean.
Form there we can go to our
Hierarchy window and create in our scene. So right click in the
Hierarchy and choose
2D Object -> Tilemap -> Rectangular. That’s going to create a grid game object with tilemap as its child. Grid game object divides the scene into blocks of given size. The size can be changed by the use of inspector:
The tilemap is the concrete graphical representation of blocks seen in the scene. To actually start painting the tilemap and adding blocks to the scene we need to use
Tile Palette window. So go to the
Window -> 2D -> Tile Palette. It will probably popup as a new window in the center of your screen so reasonable thing to do is to grab it and dock it next to your inspector tab on the right:
Create New Palette and then drag all the tile sprites into the Tile Palette window. You will be asked to select folder in which you’d like the tile palette to be.
You’d probably like to rename it from
New Palette. You can do it in hierarchy or project panel.
If you click on the palette in the hierarchy and press F2 it will allow you to rename it and also the popup should show whether to rename the file.
Important thing to note that now the editor is working in the tile palette context so you don’t see the full hierarchy of your scene. You can always go back to the full context by clicking the back arrow in the hierarchy (marked red in screenshot above).
Go back to the full hierarchy by clicking the arrow and select the
Grid from the hierarchy. Then from
Tile Palette select the paint brush tool and select the tile you’d like to paint. Now you can finally paint the tile into the scene.
You should end up with simple floor painted into the scene similar to this:
Next thing we can do is actually to add our player to the screen. To do that we have to prepare some kind of player 2d sprite representing our player. If you’ll go to the
Project window at the bottom and go to
BayatGames -> Free Platform Game Assets -> Character -> Character Animations you’ll find the folders showing possible states for our player:
Idle, Jump, Run. The problem is that we need to prepare them a bit for use in Unity.
Let’s start with
Idle animation. In the
Idle folder click
2x. This should show the Inspector on the right for the Texture 2D we selected. What we’re actually working with here is called sprite atlas. This is the texture where different images are jammed together in one image. It is done for efficiency and optimization (it’s alway faster to load only one image instead of many into the memory).
We need to adjust the import settings for the texture atlas as we’d like to use it for animation (or if we’d like to use just one tile of given atlas). First thing that we need to do is to inform the Unity that we’re working with multiple sprites in sprites atlas:
This will enable us to use
Sprite Editor and cut the atlas into pieces:
Sprite Editor simply click
Slice make sure that
Type is set to
Pivot is set to
Center and press
Slice again. That’s gonna allow us to work separately with each sprite in the atlas. To keep things neat I’m gonna move the sprite atlas from the
Bayat Games location into the
Platformer Games -> Player Sprites . In this location I’m going to keep all sprites atlases that I’ll splice.
With that we can finally create our player. Let’s go to hierarchy and add two new objects:
Spirtes as a child of
Player. This will allow us to keep the physics of the player and its representation separated.
Sprites object add
Sprite Renderer component and we can choose
2x_0 sprite just to see our player on the screen. You should see something like this in your scene:
If you run your game right now you’ll see that nothing actually happens. What we actually need to do is to add rigid body and collider to our player and floor.
Let’s start with our player. One thing to note is we’ll be adding our rigid body and box collider to the Player game object and not it’s sprite child:
We will be using
Box Collider 2D as collider and
Rigidbody 2D as rigid body. The default settings for
Box Collider 2D are fine so we don’t need to change anything there.
Fortunately the same goes for
Rigidbody 2D for our case use of
Dynamic body type is fine since we’ll be moving our character using physics by applying forces and modifying velocity.
Now let’s take a look at our
Grid -> Tilemapadd we need add two colliders two it . First is going to be the
Tilemap Collider 2D . If we take a closer look we’ll see that the collider is added to every single tile of our tilemap:
This isn’t the best way to handle collider. Calculation for colliders tend to be resource heavy and as your level will grow so also the computational requirements. Fortunately there’s a way to optimize it.
We can add
Composite Collider 2D which will merge the colliders in the continuous tiles into one. This will dramatically decrease amount of collider objects in the scene. This will also automatically add
Rigidbody 2D to our
Tilemap . That’s because
Composite Collider 2d needs it to work.
If you play your game right now you’ll see that our floor falls to the ground. This is because
Rigidbody 2D has its
Body type by default set to
Dynamic . Whenever we deal with stuff like floors or walls or other obstructions we should set the
Body type to static since we don’t expect it to move.
To make our
Composite Collider 2D work we also must tell our
Tilemap Collider 2D to actually allow
Composite Collider to merge it. You can find option
Used by composite on
Tilemap Collider 2D . So finally our options for our
Tilemap object should be:
Next thing that we need to set up is how our game uses user input. We could read the input directly into code using
Input class but this approach is rather rigid. What we’ll use is
Input System the special additional package that allow is easily configure how we translate user inputs into functional calls in our code.
In the project window use right-click and choose
Create -> Input Actions and name it
Platformer. This is what you’ll see if you click to open it:
This is the reasonable defaults provided by Unity. We have different set of maps actions maps we are like super sets of actions (for example for player in game and for UI controls).
Then for each super set we can define actions groups that allow to perform actions for different type of inputs (i.e. keyboard and gamepad both can trigger action fire weapon action). Then pressing onto each action definition for given input we can define which button triggers the action.
Let’s start working on that. Press on
+ next to
Action Maps :
Let’s name that
Player and then let’s name our
+ next to
Move and choose
Positive/Negative binding . We will use this binding to define horizontal movement of our player. Name that binding
Horizontal Movement and then we can finally add the keys on which we’d like to listen.
So select the
Negative binding. Next click on
path . After that you can find the
A key in keyboard section or you can just click on
Listen and then press
A .Set the
Positive value for
Now we must add those
Input actions to the object that we’d like to control. Select our
Player and add
Player Input component to it. We need to provide
Platformer Input actions as
Actions to it.
Ok finally we can start coding. Let’s create
Scripts -> Movement C# script where we’ll add possibility to move for our player.
We will start by defining some class variables that we’ll use in our class and we’ll get reference to
Rigidbody 2D :
Next let’s create a function that we’ll be called by our
public void OnMove(InputAction.CallbackContext ctx)
The function has to be public so that can be called from Unity. It also has to correctly defined arguments so that we can use it with
Input System. After we have that definition in place we can plug it into the
Input Actions component of our
Player and unfold
Player at the bottom. Then drag
Player into the
Move (Callback Context) and then select
On Move function from it on the right side.
Now we should read the velocity value in
OnMove function and store it. We will also apply this velocity to our
RigidBody each frame in
This actually makes our player move across the screen. Unfortunately this does not look to good as we’re not animating our movement yet. Let’s figure that out now. First let’s start by creating
Animations folder in our
Project . We’ll need to create both
To do so we need to slice that
Idle sprites in
Bayat Games -> Free Platform Game Assets -> Character -> Character Animations . Make sure to set the
Sprite Mode to
Multiple and use
Sprite Editor to slice the sprite into frames. My suggestions is also to copy
Idle sprites to
Platformer Game -> Player Sprites.
Easiest way to change them into animations is to simply drag them into the scene. This will show you a file explorer window where you can set the location where to save the animations. It will automatically create
.anim file that we can use to play animations.
So drag both sprites into the scene and save the files into
Animations folder with
To play and control our animations we need
Animations Controller . Let’s create one in
Animations folder and name it
Next in our hierarchy select
Player -> Sprites and add
Animator component and set
Player. If you double click on
Player animation controller it should open the
Window. It works using state machine pattern.
Meaning we will be changing the state of our character animation. Whenever the player is moving we will change the state to
Run and when he’s not we’re going to move to
Idle. What we can do is drag our animations into the
Next right click on the
Idle animation and select
Make Transition and connect the output to
Run animation. We also need to create the transition from
Idle. We should end up with something like this:
After that we can switch to
Parameters tab. Here we can set up some parameters for our state machine that will drive the transitions between our state. So let’s click
+ and choose
Bool parameter and name it
Next click on the arrow that is transitioning from
Run . We need to uncheck
Has Exit Time checkbox and set the
Transition Duration to 0. We also need to add transition condition so let’s click
+ next to
conditions tab. It will automatically populate with the parameter we have created:
We need to configure the transition back with the same settings. Only difference of course is that
IsRunning parameter is going to be set to
Ok the last thing is to trigger our transitions with code. Let’s start by grabbing the reference to the
Animator in our
[SerializeField] private Animator animator;
Since we serialize it we can pass it via
Unity Editor we can get it from the
Sprites child object:
The other option would be to use
GetComponentInChildren function in
Awake callback in our
Now we can finally trigger our transition using code. What we’ll do is check for the value of
_currentVelocity to trigger the parameter. We can improve our code by caching our parameter value first with:
static readonly int IsRunning = Animator.StringToHash("IsRunning");
Added at the top of our
Movement class. With that we need to add some
if checks to
This will make our animation works. Well, almost… it works if we move our character to the right. Unfortunately if we move to the left he is still looking right. We can fix it by switching the
localScale.x value to make our character turn the other way.
We just need to check whether our
currentVelocity is greater than zero and reassuring the transform value.
That should make our character animate properly.
This concludes the first part of creating 2d platformer game in Unity3D engine. I hope you enjoyed article and stay tuner for more :).
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Would you like to join our team? See our open positions here: