Blowing stuff up is fun. Blowing stuff up with friends is even more fun. Blowing your friends up? We have a winner!
Unfortunately, it’s a little difficult to secure C4 explosives along with some willing buddies willing to explore the afterlife. Thankfully, there are some alternatives.
Enter this Bomberman tutorial. Bomberman is a game where four players battle it out by strategically placing bombs across the battlefield with the goal being to blow each other up.
Each bomb has a few seconds of delay before it explodes and spews out an inferno in four directions. For additional excitement, explosions can trigger impressive chain reactions.
The original Bomberman came out in the early 80s and spinoffs have been published ever since. It’s a timeless game formula that’s still a lot of fun to play and build.
The original title was 2D, but you’re going to create a basic 3D version inside of Unity.
In this tutorial, you’ll learn the following:
- Dropping bombs and snapping them to a tile position.
- Spawning explosions by using raycasts to check for free tiles.
- Handling explosions colliding with the player.
- Handling explosions colliding with bombs.
- Handling player death(s) to determine a win/draw.
Loosen up your wrists and get ready to shout “fire in the hole”. Things are about to get really explody inside of Unity. :]
Getting Started with this Bomberman tutorial
Download the Starter Project for this Bomberman tutorial and extract it to a location of your choosing.
Open up the Starter Project in Unity and start this Bomberman tutorial. The assets are sorted inside several folders:
- Animation Controllers: Holds the player animation controller, including the logic to animate the players’ limbs when they walk around. If you need to brush up on animation, check out our Introduction to Unity Animation tutorial
- Materials: Contains the block material for the level
- Models: Holds the player, level and bomb models, as well as their materials
- Music: Contains the soundtrack
- Physics Materials: Holds the physics material of the players — these are special kinds of materials that add physical properties to surfaces. For this tutorial it’s used to allow the players to move effortlessly arund the level without friction.
- Prefabs: Contains the bomb and explosion prefabs
- Scenes: Holds the game scene
- Scripts: Contains the starter scripts; be sure to open them and read through them because they’re heavily commented to make them easier to understand
- Sound Effects: Holds the sound effects for the bomb and explosion
- Textures: Contains both player textures
Dropping A Bomb
If it’s not opened yet, open up the Game scene and give it a run.
Both players can walk around the map using either the WASD keys and the arrow keys.
Normally, when player 1 (the red one) presses Space he should place a bomb at his feet, player 2 should be able to do the same thing by pressing Enter/Return.
However, that doesn’t work yet. You need to implement the code for placing bombs first, so open the Player.cs script in your favorite code editor.
This script handles all player movement and animation logic. It also includes a method named DropBomb that simply checks if the bombPrefab GameObject is attached:
private void DropBomb()
{
if (bombPrefab)
{ //Check if bomb prefab is assigned first
}
}
To make a bomb drop beneath the player, add the following line inside the if
statement:
Instantiate(bombPrefab, myTransform.position, bombPrefab.transform.rotation);
This will make a bomb spawn at the player’s feet. Save your changes to the script and then give your scene a run to try it out:
It’s working great!
There’s a small problem with the way the bombs get dropped though, you can drop them wherever you want and this will create some problems when you need to calculate where the explosions should spawn.
You’ll learn the specifics of why this is important when this tutorial covers how to make the explosions.
Snapping
The next task it to make sure the bombs snap into position when dropped so they align nicely with the grid on the floor. Each tile on this grid is 1×1, so it’s fairly easy to make this change.
In Player.cs, edit the Instantiate()
you have just added to DropBomb()
like so:
Instantiate(bombPrefab, new Vector3(Mathf.RoundToInt(myTransform.position.x),
bombPrefab.transform.position.y, Mathf.RoundToInt(myTransform.position.z)),
bombPrefab.transform.rotation);
Mathf.RoundToInt
calls for the x and z values of the player position, rounds off any float to an int value, which then snaps the bombs to the tile positions:
Save your changes, play the scene and run around while dropping some bombs. The bombs will now snap into place:
Although dropping bombs on the map is pretty fun, you know it’s really all about the explosions! Time to add some firepower to this thing. :]
Creating Explosions
To start off, you’re going to need a new script:
- Select the Scripts folder in the Project view.
- Press the Create button.
- Select C# Script.
- Name the newly created script Bomb.
Now attach the Bomb script to the Bomb prefab:
- In the Prefabs folder, select the Bomb GameObject.
- In the Inspector window click the Add Component button.
- Type bomb in the search box.
- Select the Bomb script you just made.
Finally, open the Bomb script in your code editor. Inside of Start(), add the following line of code:
Invoke("Explode", 3f);
Invoke()
takes 2 parameters, firstly the name of the method you want to be called and secondly, the delay before it gets called. In this case, you want to make the bomb explode in three seconds, so you call Explode()
— you’ll add it next.
Add the following under Update()
:
void Explode()
{
}
Before you can spawn any Explosion GameObjects
, you’ll need a public variable of the type GameObject
so you can assign an Explosion
prefab in the Editor. Add the following right above Start()
:
public GameObject explosionPrefab;
Save your file and return to the Editor. Select the Bomb prefab in the Prefabs folder and drag the Explosion prefab to the Explosion Prefab slot:
Once you’ve done this, return to the code editor. You finally get to write the code that makes things go boom!
Inside Explode()
, add the following lines:
Instantiate(explosionPrefab, transform.position, Quaternion.identity); //1
GetComponent<MeshRenderer>().enabled = false; //2
transform.Find("Collider").gameObject.SetActive(false); //3
Destroy(gameObject, .3f); //4
This piece of code does the following:
- Spawns an explosion at the bomb’s position.
- Disables the mesh renderer, making the bomb invisible.
- Disables the collider, allowing players to move through and walk into an explosion.
- Destroys the bomb after 0.3 seconds; this ensures all explosions will spawn before the
GameObject
is destroyed.
Save your Bomb script and return to the editor and give your game a play. Put down down some bombs and bask in the fiery goodness as they explode!

Cool guys don’t look at explosions!
Add a LayerMask
The walls in the game are, luckily, bombproof. The bombs are not bombproof, and the players are definitely not bombproof. You need a way to tell if an object is a wall or not. One way to do that is with a LayerMask
A LayerMask selectively filters out certain layers and is commonly used with raycasts. In this case, you need to filter out only the blocks so the ray doesn’t hit anything else.
In the Unity Editor click the Layers button at the top right and select Edit Layers…
If necessary click on the expansion triangle in front of the word Layers to expand the list of layers if it is not visible.
Click the text field next to User Layer 8 and type in “Blocks“. This defines a new layer you can use.
Inside the hierarchy view, select the Blocks GameObject, inside the Map container object.
Change the layer to your newly created Blocks layer:
When the Change Layer dialog comes up, click the “Yes, change children” button, to apply to all of the yellow blocks scattered across the map.
Finally add a public reference to a LayerMask
so the Bomb script will be able to access the layer by adding the following line just below the reference to the explosionPrefab
.
public LayerMask levelMask;
Don’t forget to save your code.
Bigger! The Explosions Must be Bigger!
The next step is to add the iconic touch of expanding rows of explosions. To do that, you’ll need to create a coroutine.
People often confuse coroutines with multi-threading. They are not the same: Coroutines run in the same thread and they resume at intermediate points in time.
To learn more about coroutines and how to define them, check out the Unity documentation.
Return to your code editor and edit the Bomb script. Under Explode()
, add a new IEnumerator
named CreateExplosions
:
private IEnumerator CreateExplosions(Vector3 direction)
{
return null; // placeholder for now
}
Create the Coroutines
Add the following four lines of code between the Instantiate
call and the disabling of the MeshRenderer
in Explode()
:
StartCoroutine(CreateExplosions(Vector3.forward));
StartCoroutine(CreateExplosions(Vector3.right));
StartCoroutine(CreateExplosions(Vector3.back));
StartCoroutine(CreateExplosions(Vector3.left));
The StartCoroutine
calls will start up the CreateExplosions IEnumerator
once for every direction.
Now comes the interesting part. Inside of CreateExplosions()
, replace return null; // placeholder for now
with this piece of code:
//1
for (int i = 1; i < 3; i++)
{
//2
RaycastHit hit;
//3
Physics.Raycast(transform.position + new Vector3(0,.5f,0), direction, out hit,
i, levelMask);
//4
if (!hit.collider)
{
Instantiate(explosionPrefab, transform.position + (i * direction),
//5
explosionPrefab.transform.rotation);
//6
}
else
{ //7
break;
}
//8
yield return new WaitForSeconds(.05f);
}
This looks like quite a complicated code snippet, but it's actually fairly straightforward. Here's a section-by-section explanation:
- Iterates a
for loop
for every unit of distance you want the explosions to cover. In this case, the explosion will reach two meters. - A
RaycastHit
object holds all the information about what and at which position theRaycast
hits -- or doesn't hit. - This important line of code sends out a raycast from the center of the bomb towards the direction you passed through the
StartCoroutine
call. It then outputs the result to the RaycastHit object. Thei
parameter dictates the distance the ray should travel. Finally, it uses a LayerMask named levelMask to make sure the ray only checks for blocks in the level and ignores the player and other colliders. - If the raycast doesn't hit anything then it's a free tile.
- Spawns an explosion at the position the raycast checked.
- The raycast hits a block.
- Once the raycast hits a block, it breaks out of the
for loop
. This ensures the explosion can't jump over walls. - Waits for 0.05 seconds before doing the next iteration of the
for loop
. This makes the explosion more convincing by making it look like it's expanding outwards.
Here's how it looks in action:
The red line is the raycast. It checks the tiles around the bomb for a free space, and if it finds one then it spawns an explosion. When it hits a block, it doesn't spawn anything and it stops checking in that direction.
Now you can see the reason why bombs need to be snapped to the center of the tiles. If the bombs could go anywhere, then in some edge cases the raycast will hit a block and not spawn any explosions because it is not aligned properly with the level:
Finally, select the Bomb prefab in the Prefabs folder in the project view, and change the Level Mask to Blocks.
Run the scene again and drop some bombs. Watch your explosions spread out nicely and go around the blocks:
Congratulations, you've just made it through the hardest part of this tutorial!
Go ahead and reward yourself with a refreshing drink or a delicious snack, think about what you just did, and then come back to play around with reactions to explosions!
Chain Reactions
When an explosion from one bomb touches another, the next bomb should explode -- this feature makes for a more strategic, exciting and firey game.
Luckily this is quite easy to implement.
Open up the Bomb.cs script in your code editor. Add a new method named OnTriggerEnter
below CreateExplosions()
:
public void OnTriggerEnter(Collider other)
{
}
OnTriggerEnter
is a pre-defined method in a MonoBehaviour
that gets called upon collision of a trigger collider and a rigidbody. The Collider
parameter, named other
, is the collider of the GameObject that entered the trigger.
In this case, you need to check the colliding object and make the bomb explode when it is an explosion.
First, you need know if the bomb has exploded. The exploded variable will need to be declared first, so add the following right under the levelMask
variable declaration:
private bool exploded = false;
Inside OnTriggerEnter()
, add this snippet:
if (!exploded && other.CompareTag("Explosion"))
{ // 1 & 2
CancelInvoke("Explode"); // 2
Explode(); // 3
}
This snippet does three things:
- Checks the the bomb hasn't exploded.
- Checks if the trigger collider has the
Explosion
tag assigned. - Cancel the already called
Explode
invocation by dropping the bomb -- if you don't do this the bomb might explode twice. - Explode!
Now you have a variable, but it hasn't been changed anywhere yet. The most logical place to set this is inside Explode()
, right after you disable the MeshRenderer
component:
...
GetComponent<MeshRenderer>().enabled = false;
exploded = true;
...
Now everything is set up, so save your file and run the scene again. Drop some bombs near each other and watch what happens:
Now you've got some seriously destructive firepower going on. One little explosion can set your little game world on fire by triggering other bombs, allowing for these cool chain reactions!
The last thing to do is to handle players' reactions to explosions (Hint: they're not good!) and how the game translates the reaction into a win or draw state.
Player Death And How To Handle It
Open the Player.cs script in your code editor.
Right now, there's no variable to indicate if the player is dead or alive, so add a boolean variable at the top of the script, right under the canMove
variable:
public bool dead = false;
This variable is used to keep track if the player died to an explosion.
Next, add this above all other variable declarations:
public GlobalStateManager globalManager;
This is a reference to the GlobalStateManager
, a script that is notified of all player deaths and determines which player won.
Inside OnTriggerEnter()
, there's already a check to see if the player was hit by an explosion, but all it does right now is log it in the console window.
Add this snippet under the Debug.Log
call:
dead = true; // 1
globalManager.PlayerDied(playerNumber); // 2
Destroy(gameObject); // 3
This piece of code does the following things:
- Sets the dead variable so you can keep track of the player's death.
- Notifies the global state manager that the player died.
- Destroys the player GameObject.
Save this file and return to the Unity editor. You'll need to link the GlobalStateManager
to both players:
- In the hierarchy window, select both Player GameObjects.
- Drag the Global State Manager GameObject into their Global Manager slots.
Run the scene again and make sure one of the players is obliterated by an explosion.
Every player that gets in the way of an explosion dies instantly.
The game doesn't know who won though because the GlobalStateManager doesn't use the information it received yet. Time to change that.
Declare the Winner
Open up GlobalStateManager.cs in your code editor.
For the GlobalStateManager
to keep track of what player(s) died, you need two variables. Add these at the top of the script above PlayerDied()
:
private int deadPlayers = 0;
private int deadPlayerNumber = -1;
First off, deadPlayers
will hold the amount of players that died. The deadPlayerNumber
is set once the first player dies, and it indicates which one it was.
Now that you have this set up, you can add the actual logic. In PlayerDied()
, add this piece of code:
deadPlayers++; // 1
if (deadPlayers == 1)
{ // 2
deadPlayerNumber = playerNumber; // 3
Invoke("CheckPlayersDeath", .3f); // 4
}
This snippet does the following:
- Adds one dead player.
- If this is the first player that died...
- It sets the dead player number to the player that died first.
- Checks if the other player also died or if just one bit the dust after 0.3 seconds.
That last delay is crucial for allowing a draw check. If you checked right away, you might not see that everybody died. 0.3 seconds is sufficient to determine if everybody died.
Win, Lose or Draw
You've made it to the very last section! Here you create the logic behind choosing between a win or a draw!
Make a new method named CheckPlayersDeath
in the GlobalStateManager script:
void CheckPlayersDeath()
{
// 1
if (deadPlayers == 1)
{
// 2
if (deadPlayerNumber == 1)
{
Debug.Log("Player 2 is the winner!");
// 3
}
else
{
Debug.Log("Player 1 is the winner!");
}
// 4
}
else
{
Debug.Log("The game ended in a draw!");
}
}
This is the logic behind the different if-statements in this method:
- A single player died and he's the loser.
- Player 1 died so Player 2 is the winner.
- Player 2 died so Player 1 is the winner.
- Both players died, so it's a draw.
Save your code, then give the game a final run and test if the console window reads out what player won or if it ended up as a draw:
And that concludes this tutorial! Now go ask a friend if they want to share in the fun and blow them up when you get the chance. :]
Where To Go From Here?
Download the finished Bomberman tutorial Final Project if you got stuck.
Now you know how to make a basic Bomberman-like game by using Unity.
This Bomberman tutorial used some particle systems for the bomb and the explosion, if you want to learn more about particle systems, check out my Introduction To Unity: Particle Systems Tutorial.
I highly encourage you to keep working on this game -- make it your own by adding new features! Here are some suggestions:
- Make the bombs "pushable", so you can escape bombs next to you and push them towards your opponent
- Limit the amount of bombs that can be dropped
- Make it easy to quickly restart the game
- Add breakable blocks that get destroyed by the explosions
- Create interesting powerups
- Add lives, or a way to earn them
- UI elements to indicate what player won
- Find a way to allow more players
Be sure to share your creations here, I'd love to see what you guys can come up with! As always, I hope you enjoyed this tutorial!
If you have any remarks or questions, you can do so in the Comments section.
The post How To Make A Game Like Bomberman With Unity appeared first on Ray Wenderlich.