Acquaintance with the system of two-dimensional tile maps Unity provides an excellent opportunity to save the time of indie developers and game studios for prototyping and creating high-quality 2D games.
Without this system, you can spend days, if not weeks, on writing your own tile card system or processing someone else's. And this is just programming, but what about the tile map editor?
The new system is free and is built directly into the Unity editor. It provides many features that we will look at in this tutorial.
In this article, we will use a simple 2D 2D game to learn the following:
- How do tile cards work?
- How to include tile maps in Unity and configure the grid.
- How to add sprites to the project, convert them into tiles, and then add them to the tile palette.
- How to use tile editor tools to create levels.
- How to sort tiles and place them in different layers.
- How to add tiles to Unity physics.
- How to dynamically paint tiles.
- How to change prefab tiles with your own code and logic.
- How to add custom extensions and tile card scripts to a project.
Yeah, the list was big. But do not be afraid - when we start to understand, you will quickly understand how simple these tools are.
Note: in this tutorial it means that you are good at working in the Unity editor. If you think that you have not mastered it enough, then in the tutorial Introduction to Unity there is everything you need to study this tutorial. In addition, you need Unity version 2017.3 or higher.
What is a tile game?
A 2D 2D game is any game in which levels or play areas consist of many small tiles (tiles) that together form a grid of tiles. Sometimes the differences between tiles can be obvious, and sometimes they seem to be solid and indistinguishable to players.
The collection of tiles in the game is called a “tileset”, and each tile is usually a sprite, part of a spritesheet. If you want to better understand the sheets of sprites, then we have a
tutorial in which sheets of Unity sprites are described.
As you can see in this tutorial, tiles are usually squares. But they can take another form - rectangles, parallelograms or hexagons. In games, a top or side view is usually used, but sometimes 2.5D is also used in tile games.
Perhaps you already know the two most popular games that use the tile map system:
Starbound and
Terraria .
Getting Started
Download the project
materials for this tutorial and unzip the .zip file.
Launch Unity Editor and download the
Rayzor-starter project from the unpacked project materials.
Here, with what you will work in this project:
- Cinemachine / Gizmos: Unity Cinemachine is added only to implement an easy-to-use camera following the player.
- Palettes: we will store our own palettes of tiles in this folder.
- Prefabs: several prefabs created in advance, which we later use in the game.
- Scenes: here we will open and save scenes.
- Scripts: some simple scripts to control player movement, logic of trap collision and win / lose in a game. Also in this folder are the Unity Tilemap scripts from the Unity 2D Extras Github repository , which we will apply later.
- Sfx: sounds for the game.
- Sprites: 2D sprites from which we will create tile palettes. They are taken from a pack of caves and dungeons for roguelike . Author pack kenney.nl.
Game creation
Open the
Game scene from the
Scenes folder.
Click the
Play button in the editor to start the game. In the
Game window, move the hero using the WASD or “arrow” keys.
While the hero wanders over the seemingly endless background of the camera with color # 00000, being lost in the void.
To fix this, we need the tools of 2D tiles to build interesting levels and game mechanics.
Get acquainted with the palette of tiles
In the editor, click
Window -> Tile Palette to open the 2D Tile Palette window.
This window will become your best friend when working on tile games in Unity.
- This series of icons provides basic tools for tile manipulation, drawing, and deletion.
- This selector allows you to create different palettes that can be perceived as drawing palettes, in which we have “colors”, and in this case tiles.
- This selector allows you to create brushes with different behaviors. You can add your own brushes, the behavior of which differs from the default brush (for example, drawing prefab tiles with additional functionality)
Click on
Create New Palette and name the palette
RoguelikeCave . Do not change grid and cell options.
Click on
Create and choose to save the new palette in the project’s
Assets \ Palettes folder. In it, create a new folder
RoguelikeCave .
Now the folder structure of your project should look like this:
In the
Tile palette editor window,
RoguelikeCave must be selected; we still don't have any tiles at this stage:
How can an artist create his masterpieces if he has no materials?
Without closing the Tile Palette window, select the
Sprites / roguelike-cave-pack project folder and expand the
roguelikeDungeon transparent.png asset. Then select all the sprites in this list of sprites: select the first sprite, hold down the shift and select the last sprite.
Drag all selected sprites to the Tile Palette RoguelikeCave window:
Drag the sprites to the Tile Palette window and select a place for storing assets in Unity.
Create a new
Tiles folder in
Assets / Palettes / RoguelikeCave and select this folder as the storage location:
Unity will generate a tile asset for each sprite added from the sprite sheet. Wait until the process is complete, then increase the size of the Tile Palette window and admire the even rows of beautiful new tiles located in the RoguelikeCave palette:
Repeat the process described above to create a tile palette using the
Tile Palette window, but this time name the new one
RoguelikeCustom .
Place the new palette in the new folder. Name the folder
RoguelikeCustom and move it to the project’s
Assets / Palettes folder.
This time, using the process described above, use the sprites from the sheet
Assets / Sprites / roguelike-custom / roguelike-normal-cutdown-sheet.png to fill in the tiles of the new palette. Create a
Tiles folder inside the
RoguelikeCustom palette folder and drag the tile assets there:
Take care of yourself, now you know the magic of creating a tile palette!
Creating a tile map grid
Open the
GameObject menu at the top of the Unity editor (or the Unity menu bar if you're working under MacOS), click on
2D Object , and then
Tilemap to create a new Tilemap grid:
You should see a new GameObject
Grid added to the scene hierarchy. Expand it and select the embedded GameObject
Tilemap .
Think of this
Tilemap as a layer (perhaps one of many) of your game. You can add new objects to create additional Tilemap layers.
In the inspector, you will see two components that Unity automatically added to this GameObject:
- The
Tilemap
component Tilemap
used by the Unity engine to store sprites in the schema marked with the Grid
component — in our case, this is the GameObject Grid . When you first create a Tilemap, you should not worry too much about all the technical features of how Unity links between all these components. Tilemap Renderer
assigns material that will be used to render tiles in a Tilemap. It also allows you to customize the sorting properties of this Tilemap layer.
Rename GameObject
Tilemap to
BaseLayer .
Using various tile palette drawing tools
Switch to Scene mode in the editor.
Without closing the Tile Palette window, select the RoguelikeCave palette, and then select the
brush tool (or press
B ). Select a sand tile as shown below:
In the Scene window, move the cursor to the grid next to the player. Brush with sand tile will snap to the grid.
Holding and holding the left mouse button, draw a rectangular area around the player. It will be drawn on the BaseLayer Tilemap layer:
Drawing large areas can be monotonous, so there is a
Filled Box brush that can be used to paint large areas. In the Tile Palette window, click on the
square brush icon (or press
U ).
Go back to the editor and draw a larger rectangle around the player by clicking and holding the left mouse button while dragging the cursor from the top left to the bottom right corner:
Although we have added a bit of color to the game, this sand dungeon looks dull. It's time to add some details!
Use the
GameObject -> 2D Object -> Tilemap menu option to create a new Tilemap layer. This time it will be the only object created in the hierarchy, because we already have a suitable Grid. Rename this layer to
DungeonFloorDecoration :
In the Tile Palette window, switch
Active Tilemap to the
DungeonFloorDecoration layer:
Select the
brush tool (
B ), then draw objects scattered on the map in the Scene window:
Turn off and then re-enable GameObject
DungeonFloorDecoration in the hierarchy to see how the drawing on the active Tilemap changes the DungeonFloorDecoration layer, and all the tiles that you draw fall on this new layer:
Create a new Tilemap layer using the
GameObject -> 2D Object -> Tilemap option again . Call it
Collideable . Later we use it to create walls and borders.
Switch Active Tilemap in the Tile Palette window to
Collideable . Select the brush tool (
B ), and then draw the following tiles to build a wall around the play area. The red areas in the image below are new parts that need to be added:
Look at the screenshot of the Tile Palette window shown below to find out where to find the tiles needed to build the wall. Do not forget that you can use CTRL-Z or CMD-Z to undo the action or erase errors using the current brush (while holding
Shift ):
Start the game in the editor and try to get through the wall:
You did not expect this?
The problem is that we just drew the standard tiles and did not apply the magic Unity physics to the Tilemap layer yet.
Select GameObject
Collideable and add a new component by clicking the
Add Component button in the
Inspector window; In the search field, enter
Tilemap Collider 2D :
This component was created specifically for 2D Unity tile games. It simply applies the shape of the physical collider to all the tiles of the layer to which it was added, without performing any other work.
Start the game again and try to go through the wall. Access is denied!
Note: sometimes when moving the camera you can see small black lines between some tiles. It seems that this is a problem of camera movement in projects with the 2D Tilemap Unity system. You can almost completely get rid of it by turning off Anti-Aliasing in the graphics settings. However, even if this is done in the draft project, the effect is still slightly noticeable. The solution to this problem can be to add your own camera motion script with pixel offset. A good discussion of this problem can be found here .
Collisions work well, and you might think that this is enough. But so far the colliders are not optimized effectively. In Scene mode, zoom in on a part of the wall and look at the contours of the colliders:
There is a collider around each tile. The middle sections of the walls do not need these additional colliders.
After choosing GameObject
Collideable , add the
Composite Collider 2D component to it. This will also automatically add RigidBody2D.
Set the
BodyType RigidBody2D parameter to
Static , and then select the
Use by Composite checkbox in the
Tilemap Collider 2D component:
After this, you will notice that these unnecessary square colliders in the middle of the walls will disappear.
Complete the creation of the walls by adding them up and closing them at the top, about 16 tiles high. Do not forget. that Collideable should be selected as the Active Tilemap of the Tile Palette
window :
The site of the dungeon will not be any difficulty for our hero without obstacles. Now we will begin work on the creation of the room of death, supplemented by beautiful ancient marble corridors. After overcoming all these obstacles, the player is awaited a reward - a mountain of gold.
To draw these corridors, we will use a special tile brush
Rule Tile . As you saw at the beginning of the tutorial, additional tile scripts from the
Unity 2D Extras Github repository have already been added to the project. One of them is the Rule Tile.
Rule Tile allows us to set rules about which tiles to draw depending on the adjacent tiles we have.
Right-click on the project
Prefabs folder and select
Create -> Rule Tile (this item should be at the top of the menu). Name the new element
MarbleFloorRuleTile :
Select this new
MarbleFloorRuleTile and use the inspector to set the
Default Sprite to
roguelikeDungeon_transparent_335
. Then add a new Tiling Rule by clicking on the
+ icon. Select the
roguelikeDungeon_transparent_339
value for the
Sprite of this rule and click on all the external squares in the rule scheme so that each one has a green arrow pointing out:
Using the box fill brush tool (
B ) in the Tile Palette window and selecting the BaseLayer
Tilemap layer, draw a straight section of the marble wall. It is necessary that it covers all the free space of the floor.
You may notice that when we do this, the layer will cover the tiles of the walls with the collagers, because the order of the layers has not been set yet. This is easily fixed by selecting GameObject
Collideable and changing the
Order in Layer of the
Tilemap Renderer component to a higher value (
5 will suffice):
Return to the project's
Prefabs folder, open the Tile window and select the RoguelikeCave palette, and then drag
MarbleFloorRuleTile to an empty space on the palette:
Use the box fill brush and paint several marble floor sections in the room:
Note that a customized rule tile, completely surrounded from all angles and edges, becomes decorated with a tile (a sprite selected in the Tiling Rules editor).
It is a trap!
No, we will not add Admiral Akbar to the game as a character. We will create a trap prefab tile brush, which we will use to draw traps that shoot rotating blades!
Create a new empty GameObject in the hierarchy and name it
ShootingTrap . Create an empty child GameObject in ShootingTrap. Call it
Sprite :
Select
Sprite and add the
Sprite Renderer component to it. Set
Sorting Layer to
Player , and
Order in Layer to
1 , so that it is rendered on top of the other layers. Select the field
Sprite , and as a sprite, put
roguelikeDungeon_transparent_180 .
Now rotate the Transform of the
Sprite object by
-90 along the
Z axis:
Next, go back to GameObject
ShootingTrap and add a new component using the inspector. In the search field, find the
Shooting Trap and attach this script.
This script has been added to the project files you downloaded; in fact, every two seconds it starts a corutin, creating an instance of the prefab of the rotating saw blade (or any other prefab) in the current position of the trap.
Set the
Item to Shoot Prefab component of the Shooting Trap component to
Projectile (the prefab is located in
/ Assets / Prefabs ):
Run the game again in the editor and use the Scene mode to find the trap. She works!
Drag a copy of
ShootingTrap from the hierarchy to the project's
/ Assets / Prefabs folder to create a prefab. Remove ShootingTrap from the hierarchy.
We use another tile brush script called
PrefabBrush to create a brush that can draw prefabs on Tilemap layers.
Right-click on the project's
/ Assets / Prefabs folder and select
Create -> Prefab Brush . Name the object
PrefabBrush .
Use the inspector to set the
Prefabs Size PrefabBrush parameter to
1 , and the
Element 0 parameter to
ShootingTrap .
Create a new Tilemap layer called
Traps in the
Grid and open the Tile Palette window.
Select the regular tile brush (
B ) and use the drop-down menu at the bottom of the Tile Palette window to select the
PrefabBrush . Select Active Tilemap
Traps as the layer and use the Scene window to draw several prefabs of traps along the left border of the room.
Deploy the GameObject
Traps hierarchy and experiment with
Shoot Start Delay for each value on each Gameobject
ShootingTrap using the Shooting Trap script in the inspector. Add to the value of each trap 0.25, ie:
- First ShootingTrap -> Shoot Start Delay = 0.1
- Second ShootingTrap -> Shoot Start Delay = 0.35
- Third ShootingTrap -> Shoot Start Delay = 0.6
- And so on...
Start the game and pass the test if you dare.
Final goal
The purpose of this mini dungeon is to get a pile of gold. Glory and wealth await those who get to it, avoiding the deadly flying blades.
Create a new Tilemap layer in the GameObject
Grid called
Goal . Select
Goal and change the value of
Tilemap Renderer Order in Layer to
2 :
Without closing the Tile Palette window, make sure that PrefabBrush is still selected. Make
Element 0 refer to the
Goal preset from the
/ Assets / Prefabs folder of the project.
This is a prefab with a sprite of a mountain of gold, with Box Collider 2D with Is Trigger enabled, an added sound source, and with a simple
Goal.cs
script that reproduces the sound of reaching the goal and restarts the level when the player enters the trigger area.
Use the standard tile brush to draw one target prefab tile at the top of the room behind the traps:
Start the game again and try to reach the goal. When you get to this tile, the
OnTriggerEnter2D()
logic from
Goal.cs
, playing a sound effect and restarting the level.
Finishing touches
Now the dungeon is too light and free. We can add style to it by switching to a 2D sprite material that can respond to light.
Select the Player, Goal and ShootingTrap objects Sprite, and have the
Material Component Sprite Renderer use the
SpriteLightingMaterial :
This is a material with a
Sprite / Diffuse shader attached to it. It allows scene lighting to affect sprites.
In the GameObject
Grid, select the
BaseLayer, DungeonFloorDecoration, Collideable, and Goal objects, and then use the inspector to also use the Material
SpriteLightingMaterial in the
Tilemap Renderer Material .
Then select GameObject
Lights Directional light and lower the
Intensity Light to
0.3 .
So much better!
You will also notice that the Player carries with him a
Point Light , that is,
Lantern shining around him.
Now, when the sprites in the scene use the appropriate material, Unity's lighting affects all the surrounding sprites.
Drag two copies of the FlickerLight
prefab from the
project 's
/ Assets / Prefabs folder into the Scene and place them in the GameObject
Lights .
Set the first prefab position
(X: -11.25, Y: 4, Z: -1.35) , and the second -
(X: 2.75, Y: 4, Z: -1.35) .
Create a new Tilemap layer called
WallsAndObjects and set the
Tilemap Renderer Order in Layer inspector to
15 . Don't forget that
Material also uses
SpriteLightingMaterial .
Switch the brush of the tile palette back to
Default Brush , and the
Active Tilemap to
WallsAndObjects .
Use the brush tool (
B ) to draw two “light of the lanterns” tiles under each of the new FlickerLight, which we placed at the corners of the initial area:
Time of difficulty
See if we can further improve the dungeon. Use the Tilemap
WallsAndObjects layer to create bookcases at the top of the dungeon room using another tile palette called
RoguelikeCustom . Also draw one or two cracked wall pieces.
Go back to the Tilemap
DungeonFloorDecoration layer and add some more details to the marble floor, for example, cracks on several tiles:
Congratulations, you have completed your first mini dungeon level! As a result, you should have something like this:
Where to go next?
If you missed a step, you can look at the finished result of this tutorial by opening the Unity
Rayzor-final project from the downloaded
materials .
In this tutorial we learned a lot, but like in any other business, there is always something else!
There are interesting scripts for tile brushes that are not covered in this tutorial. Read about them
here and see if you can use them.
You can also explore the creation of animated tiles
here .