How to Implement Movement in Different Genres of Games in Unity
In this very moving tutorial, learn how to implement movement from many different genres into your Unity games — both 2D and 3D.
Version
- C# 7.3, Unity 2019.3, Unity

People tend to expect certain types of movement in certain types of games. If you’re playing a platformer, you expect to be able to run and jump. If you’re playing a Diablo clone, you expect to point and click to move your characters. So if you’re developing a game, it’s a good idea to know those rules of movement… even if it’s just so your mind-blowing game can break them!
In this tutorial, you’ll learn how to implement four types of movement in different genres in Unity. You’ll build a simple game with one backstory featuring two quirky characters, Catto and Ratto. See how they come to life in four different contexts:
- 2D Platformers
- 2D Top Down View
- 3D Click to Move
- 3D Tank Movement
This tutorial also requires that you have Unity 2019.1.3 or later installed.
Getting Started
Download the project using the Download Materials button at the top or bottom of this page, then unpack the files and open the starter project in Unity. Check out the folder structure in the Project view:
This tutorial follows a top-down approach. Each subfolder contains everything you need to get started in each genre:
- Models
- Prefabs
- Scenes
- Scripts
- Textures
Now that you’ve taken a look at your project materials, take a moment to think about the types of movement in the games you know and love.
Different Types of Movement in Games
While there’s a difference between game genres and the types of movement they use, the two concepts are so closely related that people often confuse them. That doesn’t mean that you couldn’t have a Resident Evil-style game where your character can fly, for example, but remember that restricted movement is part of what makes those games scary.
As with everything in art, you must learn the basics before creating your own style. Genres give you a starting point for choosing the movement types for your games.
Moving in 2D Versus 3D
Completely real 2D worlds are impossible. 2D and 3D are just models drawn to reflect people’s perceptions. Check out what Catto looks like in 2D and 3D:
In this tutorial, you’ll work with both 2D and 3D movement. But first, you need to learn about one important concept: Transforms.
Understanding Transforms
A Transform consist of 3 components. The Position, which is basically a point in 3D space. The Rotation, which defines the object’s orientation in 3D space. Finally, the Scale, which defines the object’s size.
In Unity, you can see these 3 components of a Transform as follows:
Notice the values for Position, Rotation and Scale each have X, Y and Z values. Each of these X, Y and Z sets is known as a Vector3.
Now that you have that information under your belt, you can move on to your first type of game: 2D platformers.
Implementing 2D Platformer Movement
For your first step, you’ll work on creating movement in a 2D platformer. Some examples of published games in this field are: Super Mario Bros., Sonic, Castlevania, Ghouls ‘n Ghosts, Rayman Legends, Mega Man, Metroid and Ninja Gaiden.
Many people think that platformers are the easiest to code, just because they look simple. A character jumps from one platform onto another, how hard can that be, right? Actually, 2D platformers today can be very complex. Soon you’ll see why.
Setting Your Scene
Open the scene in RW/2D Platformer Movement/Scenes.
This is the Hierarchy view:
Expand Player Objects. You’re going to work on PaperCatto.
If you don’t see PaperCatto in the Scene view, here’s a sweet trick: Select it in the Hierarchy, press the F key in the Scene view, then press the 2D View button.
Just like this:
Adding Movement
There are two types of movements:
-
Translation movement is a point-to-point type of movement in a physical space. In other words, it makes the character move from position
A
to positionB
. - Emotional movement isn’t a technical term, but you’ll use it in this tutorial to cover movements the character makes without translating. For example, gestures, breathing and hand-waving are motions that convey intentions or feelings. Thus, emotional.
With PaperCatto still selected, give Catto some physical properties. This will allow Catto to translate, or move. Add a Rigidbody 2D:
To make Catto show feelings and attitudes, add an Animator:
Finally, Catto needs a Box Collider 2D to be able to collide with other objects:
Now press the Play button.
Oops, that looks uncomfortable! At least it works. :]
Customizing the Movement
So Catto can move now, but you still need to make some adjustments to make him move just right. Expand the Box Collider 2D and click the Edit Collider button.
You should now be able to edit the bounds of the 2D collision box. Expand the bounds of the collision box so that it covers Catto entirely.
You can click and drag the handles of the collision box to make it fit.
Change the Gravity Scale to 2 in the Rigidbody 2D. This controls the gravity amount that’s applied to Catto. A low value like 1 for example would make Catto jump extremely high, as if Catto was on the Moon. In this instance 2 makes the jumping force in this particular case feel much more natural.
Finally, under Constraints, make sure you check Freeze Rotation Z. This prevents Catto from falling over while he runs around.
Implementing the Animator Controller
Last, but not least, hook up the Animator Controller. With PaperCatto selected, expand the Animator then select PaperCatto as the Controller:
Press Play and… Voilà! Isn’t that the most beautiful paper cat you’ve ever seen?
Writing a 2D Platformer Movement Script
OK, so PaperCatto is moving, but you still need him to react correctly to the user’s input. To do that, you’ll need a script.
Imagine you want to create a Super Mario Bros.-like game starring Catto. What kind of movement do you need? Well, you’ll need to translate Catto on the X and Y axes and rotate him:
- The
X
axis determines if Catto runs right or left. - The
Y
axis allows translation up and down for jumping and falling. - A rotation around the
Y
axis lets you rotate Catto so he faces the correct direction while moving.
Here Catto is being translated along the X-axis, moving him from left to right and back again:
Here Catto is being rotated around the Y-axis, flipping him from left to right and back again:
Moving Catto Right and Left
Now that you know what kind of movement you want Catto to have, it’s time to write the script that will implement it.
Start by dragging and dropping CattoMovement.cs to PaperCatto to add the script as a new component:
The next step is to write your script.
Double-click CattoMovement.cs so you can modify it.
The script will have three major variable groups.
The first group stores the components. Add these two lines at // 1
:
private Rigidbody2D cattoRigidbody2D;
private Animator cattoAnimator;
These two lines hold information to move and animate Catto respectively.
Here, you structure the variables to follow the “Protection, Type and Name” logic:
Notice that the simpler the variable names are, the easier it is to read them.
To use the Animator and the Rigidbody 2D, you need to tell Unity to remember them. So now, you must tell Unity what to do and where to find that information.
Add the following code so Start
looks like this:
void Start()
{
cattoRigidbody2D = GetComponent<Rigidbody2D>();
cattoAnimator = GetComponent<Animator>();
}
These two lines tell Unity: “Hey, Unity, cattoRigidbody2D
is a component of Catto, so go find it there and please remember it. Then, do the same with cattoAnimator
.”
Now, you need to keep track of Catto’s state. For example, you need to know if Catto is touching the ground or jumping.
The second group stores booleans. Add the following lines of code at // 2
:
private bool cattoIsFacingRight = true;
private bool cattoIsJumping = false;
private bool cattoIsGrounded = false;
The Boolean cattoIsFacingRight
checks if Catto is actually facing that direction. cattoIsJumping
tracks if he’s in the air, while cattoIsGrounded
tracks if he’s currently touching the ground. Both of those are false
by default.
Making the names self-explanatory saves you time, especially if you have to go back to debug your code after not working on the project for a while.
Giving Catto the Ability to Jump
This last group of variables stores the input and a special component to enable jumping. Add these six variables at // 3
:
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask ground;
public float moveInput;
public float cattoSpeed;
public float cattoJumpForce;
groundCheck
uses a groundCheckRadius
to evaluate if Catto is on the ground.
LayerMask
is a handy Unity tool to separate and order the world space into tiers. In plain English, it says: “Hey, Unity, these two objects are in the same space, so they should interact with each other.” In this case, Catto and the floor are in the same space, so they collide.
The last three variables store the float numbers that will ultimately drive Catto’s movement.
Moving on, Update
is an excellent place to poll for input, since this function is called every single frame.
Catto won’t find Ratto unless he can move so keep it up!
Finishing the Movement
There are two tasks ahead: Check if Catto is really on the ground and check the input coming from the keyboard.
Add the following lines in Update
:
cattoIsGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, ground);
moveInput = Input.GetAxis("Horizontal");
Physics2D.OverlapCircle
is a handy built-in function that informs Unity when two objects are colliding in a given area. You declared groundCheck
and groundCheckRadius
to take advantage of this function.
The variable moveInput
caches the horizontal axis of the keyboard. Pop quiz: Do you know what this value’s type is?
[spoiler title=”Solution”]
Yes! It’s a float
. Which correlates with the X-component of a Vector3.
[/spoiler]
Next, you’ll need to add four conditions to the movement logic. You’ll tackle these, one by one.
Adding Conditions to the Movement
First, add this code below the two variables you added in the last section:
// 1
if (cattoIsGrounded)
{
cattoAnimator.SetFloat("Velocity", Mathf.Abs(moveInput));
}
This value on the animator controls whether Catto looks like he’s walking — when he has a large velocity — or standing still — when his velocity is close to zero.
This translates as “If cattoIsGrounded
is true
, set the animator’s Velocity
to the value of moveInput
. Although moveInput
could be positive, it could also be negative so please use Math.Abs
so moveInput
stays positive. Thanks, C#. Bye.”
Add the second condition as follows:
//2
if (Input.GetButtonDown("Jump") && cattoIsGrounded)
{
cattoIsJumping = true;
cattoAnimator.SetTrigger("Jump");
}
This if
statement checks if the player is pressing the Jump button and if Catto is really on the ground. If so, Unity will consider it true
. If both are true, then it sets cattoIsJumping
to true
.
Finally, as before, this code says: “Hey, Unity, grab the Animator and set the trigger of Jump so Catto looks like he’s jumping.”
Here’s the third condition:
//3
if (Input.GetKeyDown(KeyCode.DownArrow) && cattoIsGrounded)
{
cattoAnimator.SetBool("Crouch", true);
}
This time, you check if the user is pressing the Down Arrow key and if cattoIsGrounded
is true
.
If so, you say: “Hey, Unity, please go to the cattoAnimator
and set the Crouch
Boolean to true
so Catto looks like he’s crouching. Thanks.”
And for the last condition:
//4
else if (Input.GetKeyUp(KeyCode.DownArrow))
{
cattoAnimator.SetBool("Crouch", false);
}
If the player has just released the Down Arrow key, go to the cattoAnimator
and set Crouch to false
. This makes Catto stand up again.
You’ve just implemented some pretty important movements: walking, jumping, crouching, and standing up again. Next, you’ll do something even fancier!
Flipping Catto
For your next step, you’ll write a custom function called FlipCatto
. Guess what it does!
Add this code:
private void FlipCatto()
{
cattoIsFacingRight = !cattoIsFacingRight;
Vector3 cattoScale = transform.localScale;
cattoScale.x *= -1;
transform.localScale = cattoScale;
}
Notice that you set cattoIsFacingRight
to its opposite value every time you call the function.
Then you store a Vector3
named cattoScale
and pass it the current scale of Catto. You multiply the cattoScale by a negative 1, which gives you the opposite image. That’s how you flip Catto over.
Finally, to work properly, the flipped image is set as the new default image until Catto flips again.
Piece of cake, right?
Flipping Catto to Match His Movements
From now on, the code goes inside FixedUpdate
because this is where Unity calculates physics.
Add this code:
cattoRigidbody2D.velocity = new Vector2(moveInput * cattoSpeed, cattoRigidbody2D.velocity.y);
Here, you set the velocity
vector of the Rigidbody 2D. To move left and right, you set the X
axis to be the moveInput
from the keyboard at the speed of cattoSpeed
, while keeping the Y
axis untouched. You’ll get to jumping in a moment.
You’re down to the last three conditions!
First, add these two if
statements below:
if (cattoIsFacingRight == false && moveInput > 0)
{
FlipCatto();
}
else if (cattoIsFacingRight == true && moveInput < 0)
{
FlipCatto();
}
In English, the first statement says: "If Catto is not facing the right direction and someone presses a key to move to the right: Flip Catto." The else if
is the opposite: "If Catto is facing right and the input points to the left: Flip Catto."
Now, for the last tweak, add this code below:
if (cattoIsJumping)
{
cattoRigidbody2D.AddForce(new Vector2(0f, cattoJumpForce));
cattoIsJumping = false;
}
This part simply uses a built-in Unity function called AddForce
. You add force specifically to the Y
axis of Catto's Rigidbody2D
. Note that you check if Catto is jumping before doing anything else.
Lastly, you set cattoIsJumping
to false. So the next time he's on the ground, he can jump.
Go back to the Hierarchy
, find CheckGround inside PaperCatto and drag and drop it through the Inspector.
Try these values:
- Ground Check Radius = 0.07
- Ground = Ground
- Catto Speed = 6.11
- Catto Jump Force = 550
One last tweak. Go to CheckGround and set it's Position to -1.18
on the Y-axis:
Finally! Press Play and marvel at such cat-ness!
Coding 2D Top Down Movement
Top down movement is when the user perceives one of the axes of movement as planar. That is, you perceive Catto going to the background when you press Up. Compare that with PaperCatto, which jumps on the spot when you press Up instead.
Published games in this genre include: Bomberman, Golden Axe Warrior, The Legend of Zelda, BattleShip and HALO Spartan Assault.
Hooking up Elements
Open the scene in RW/2D TopDown Movement/Scenes.
Now, in the Hierarchy, select Player Objects ▸ Catto ▸ Catto, the one with the Sprite Renderer.
Add the following components in the Inspector:
- A Rigidbody 2D
- A Box Collider 2D
- An Animator
Here's a challenge for you: Try adding these elements on your own. If you have any trouble, follow this aid:
The Animator won't work without an Animator Controller. So, go to 2D TopDown Movement/Models/Catto and find the CattoAnimator controller. Drag and drop it into the Animator in the Inspector:
Press Play and... Catto falls down. You need to adjust the Rigidbody 2D to fix that. Gravity's causing Catto to fall so set the Gravity Scale property to 0
and try again.
Excellent! Catto stays put. He looks like he's actually on the floor from this perspective. He still can't move, though.
Writing a 2D Top Down Movement Script
Go to 2D TopDown Movement/Scripts and drag and drop TopDownMovement.cs into Catto. You can also do this:
Perfect! Double-click the script in the Inspector to edit it. This script seems much simpler than the previous one.
Now, add these three variables:
public int velocity;
private Vector3 movement;
private Animator cattoAnimator;
In Start
, you tell Unity what to do with cattoAnimator. Use GetComponent
so Unity associates the name cattoAnimator
with the Animator attached to the GameObject.
Add this code:
cattoAnimator = GetComponent<Animator>();
As you did before, use Update
to get input from the keyboard. Add this code:
movement = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
cattoAnimator.SetFloat("Horizontal", movement.x);
cattoAnimator.SetFloat("Vertical", movement.y);
cattoAnimator.SetFloat("Amount", movement.magnitude);
transform.position = transform.position + movement * velocity * Time.deltaTime;
Breaking that up:
The variable movement
contains the information from the horizontal and vertical axes from the keyboard.
It would go something like this:
The three calls to cattoAnimator
use SetFloat
, a built-in Unity function. Basically, it translates as: "Hey, Unity, look for Horizontal
in cattoAnimator
. Once you have it, pass the value of movement
to it."
In this case, movement.x
is just the X
axis component. That is to say:
What about the last call? What's magnitude?
Magnitude is the result you get from two vectors fighting each other. As you need a diagonal movement, C# calculates magnitude
for you.
Almost there... Don't forget to set the Velocity in the Inspector. 3
is a good value to start with.
Press Play and...
Done! But wait, there's more.
Go to 2D TopDown Movement/Scripts and add CollectCoins.cs to Catto. Now you can actually play the game.
Excellent! You finished the movement for your 2D top down game.
3D Click to Rotate and Move
Welcome to 3D worlds! From now on, all the games you'll cover are in 3D space.
Click to rotate and move games use the Diablo type of movement, where you click something to get contextual information and/or to move to a specific place.
Other examples of published games in this genre include: League of Legends, Age of Empires, Grim Fandango and Monkey Island.
Hooking up Elements
Open the scene in 3D ClickToRotate Movement/Scene.
So, by now you know what to do: You need to hook everything up first. Add the following components to Catto:
- A Box Collider
- A Rigidbody
- An Animator
This is how to do it:
You also need to edit the Collider's size. Tip: switch to 2D view to help with sizing.
Expand Rigidbody in the Inspector. Go to Constraints, then freeze the rotation in X
, Y
and Z
by checking the boxes.
To hook up the CattoAnimator, expand Animator in the Inpector. Go to 3D ClickToRotate Movement/Models/Catto/Animator and drag and drop it into the Controller.
You can do the same for the Avatar, or you can just hook it up in the Inspector:
Finally, make sure to check Apply Root Motion.
Here's how the final result looks:
Press Play. Catto will show the default idle animation, although he can't move yet.
So now you've set Catto up for animations. Next, you'll get him moving!
Adding a NavMesh Agent
There's a special module Catto needs called a NavMesh: Nav for navigation, Mesh for... er... mesh :V. Seriously, it is a mesh: A very primitive shape that stores information about distance, position and other simple calculations.
The Agent is a program that performs certain tasks for you automatically.
A NavMesh Agent needs a NavMesh to work.
Look for Nav Mesh Agent in the Inspector and add it to Catto. The following settings work fine:
Feel free to experiment though, especially with the steering.
Writing a Click to Rotate and Move Script
Open ClickToMove.cs in 3D ClickToRotate Movement/Scripts.
Add the following line to the top of the file:
using UnityEngine.AI;
This gives you access to NavMeshAgent
.
Then add these three variables at the top of the class:
public Animator cattoAnimator;
public NavMeshAgent cattoNavigation;
private Transform targetDestination;
This time, you're writing a NavMeshAgent
variable type. But you already know how this works.
As you did previously, you initialize variables in Start
:
void Start()
{
cattoNavigation = GetComponent<NavMeshAgent>();
cattoAnimator = GetComponent<Animator>();
}
There's a must-have function for click and move games: Physics.Raycast
.
Add this code in Update
:
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
{
cattoNavigation.destination = hit.point;
cattoAnimator.SetBool("Walking", true);
}
}
if(cattoNavigation.remainingDistance <= cattoNavigation.stoppingDistance)
{
cattoAnimator.SetBool("Walking", false);
}
What's happening here? When the player presses the left mouse button, the current position of the mouse on screen (a 2D coordinate) is converted into a ray with ScreenPointToRay
. The ray is then cast into the 3D scene with Physics.Raycast
, a technique known as hit testing. The out
keyword specifies that the hit results should be stored in the provided hit
parameter.
Finally, you set cattoNavigation.destination
to hit.point
once the ray-cast hits something, which should be where the mouse was clicked in 3D space.
The call to the cattoAnimator
, as you saw before, asks for the Walking
animation.
In plain English, "Hey, Unity, shoot a ray where I clicked and set Catto's destination to the place on the ground where that ray hits."
The last if
compares the distance between the two points: where you clicked and where Catto should stop moving. You can change this value in the Inspector.
Add the script ClickToMoveto Catto and run your game. Follow the path to find Ratto!
Congrats! You've learned how to move a character in three different game types. Just one more to go.
3D Tank Movement
The idea that tanks have to stop moving to turn is widely spread across the Internet. That's why this kind of movement is called tank movement. However, the first tank was the Mark I, and it had good turning capabilities, even while moving. Contrary to popular belief, tanks can turn and move at the same time, and so do characters in games with this type of movement.
Anyway, here's the tank-type of movement in a nutshell:
- Up is always forward for the player, from the character's perspective.
- When you press left or right, the character performs a stationary turn.
Published games in this genre include:
,
and
.
Hooking up Elements
Open the scene in RW/3D Tank Movement/Scenes.
Select Tankatto in the Hierarchy under Player Objects.
You know the drill by now. Can you think of the components for this one, in 3D?
[spoiler title="Solution"]
Tankatto needs a Box Collider to interact with the world and a Rigidbody that the player will move and control.
[/spoiler]
Here's a visual aid:
Remember to edit the collider:
Go to 3D Tank Movement/Scripts and drag and drop TankMovement.cs onto Tankatto. Then open it so you can edit it.
Here's how it should look after adding the rest of the components:
Writing a Tank Movement Script
Your initial script has six different variables. As before, each relates to something you need to move or animate Catto. Three have to do with speed, one is the Rigidbody and two are for the input.
Add these variables at the beginning of the script:
public float tankSpeed;
public Rigidbody tankRigidBody;
public float movementInput;
public float turnInput;
public float movementSpeed;
public float turnSpeed;
A challenge: Which component will you cache during Start
?
[spoiler title="Solution"]
YAY, tankRigidBody
.
tankRigidBody = GetComponent<Rigidbody>();
[/spoiler]
Another mini challenge: Where would you cache turnInput
and movementInput
?
[spoiler title="Solution"]
That's right, during Update
.
[/spoiler]
turnInput = Input.GetAxis("Horizontal");
movementInput = Input.GetAxis("Vertical");
As you know, this type of game relies on two types of movement: turning and moving forward. So for your next step, you'll teach Catto how to turn.
Turning Catto
This time, you need to calculate the physics of Catto's movement in FixedUpdate, but you'll learn a clean way to do so. Instead of writing and managing all the code inside Unity's function, write it separately.
Add these short lines inside FixedUpdate
:
Move();
Turn();
As you see, the names of the functions are representative of the actions.
Now, add all this code to make Turn()
a nice separate function:
private void Turn()
{
float turn = turnInput * turnSpeed * Time.deltaTime;
Quaternion turnRotation = Quaternion.Euler(0, turn, 0);
tankRigidBody.MoveRotation(tankRigidBody.rotation * turnRotation);
}
What happens here?
Take into account that turnInput
and turnSpeed
are read multiple times per second. You must take control of the situation.
So, you pass turnInput
, you multiply it by turnSpeed
to get a good number, and then restrain the time cycle to roughly a second via Time.deltaTime
.
fixedDeltaTime
, but it's outside the scope of this project.
This calculation gives you a refined number, which you simply call turn
.
The image below shows the flow:
Moving on to turnRotation
, you see a Quaternion.Euler
function. The theory behind Quaternions is vast and complicated. Suffice it to say, it has to do with rotation.
Unity's function, MoveRotation(Quaternion rot)
, forces you to use a Quaternion. But, wait, aren't rotations a Vector3 in Unity, as it says at the beginning of this tutorial?
Unity fixes that problem for you. Quaternion.Euler takes three numbers: X
,Y
and Z
.
In this context, can you guess on what axis you rotate Catto?
[spoiler title="Solution"]
If you guessed Y
, you would be correct! :]
[/spoiler]
You already have a number... the number in turn
. So, pass it as Y
into Quaternion.Euler(X, Y, Z)
.
It looks like this: Quaternion.Euler(0, turn, 0)
.
The last function MoveRotation
takes the current Tankatto's rotation and multiplies it by the turnRotation
you just calculated. Have a look at the flow:
Awesome!
Moving Catto
Now, the last step: Getting Tankatto moving forward. To start, create a new function called Move()
like so:
private void Move()
{
Vector3 movement = transform.forward * movementInput * tankSpeed * Time.deltaTime;
tankRigidBody.MovePosition(tankRigidBody.position + movement);
}
This last part takes care of movement... it's pretty much the same as the previous one.
As before, you store a variable that holds the input of your keyboard, the speed you defined through the Inspector and Time.deltaTime
.
Then, why is movement
a Vector3
this time? That's easy: transform.forward
is a Vector3(0, 0, 1)
.
Finally, MovePosition
takes movement
and adds it to Tankatto's current position.
Tankatto can't move yet. Remember to set the values in the Inspector. You can use these numbers, or you can adjust them as you see fit:
- Tank Speed = 6
- Movement Speed = 40
- Turn Speed = 60
Press Play and test if everything works as intended.
You might be thinking: Where's the fun in translating and rotating a tank?
Remember Tankatto has a Missile Logic component in the Inspector, but learning how it works isn't part of the tutorial. It's just there to spice things up, now that you've come this far. :]
Click your mouse and wreak havoc!
By the way, contrary to what it seems, no rats have been harmed in the making of this game genre.
Catto and Ratto are good friends. Missiles in this game are just dummies, the point of the game consists is to push the other off the platform.
Where to Go From Here?
Congratulations on finishing this tutorial! Remember, you can get the completed project by pressing the Download Materials button at the top or bottom of this tutorial.
Extra challenge!
Genre bender, baby! Try to mix two or more genres into one game. Mixing is the best way to discover new things. For example, try to bring PaperCatto into 3D Tank Movement as if it were a paper target. Also, you can try to make moving targets.
You definitely want to check this out to increase your chi as a game developer:
How to Create a Bomberman Game in Unity. Or, if you like videos, watch this impressive series by Brian Moakley Beginning C#.
Thanks so much for reading and following along with this tutorial. If you have any questions or comments, feel free to join the discussion below!
Comments