Creating a 2.5D Side Scrolling Game

Creating a 2D character controller

Simon Truong
7 min readJul 29, 2023


The first focus in creating our 2.5D game is to setup the character controller and have everything working in a quick prototype setting. This will allow us to test for faults and issues that might occur during gameplay without wasting too much time designing and drawing character sprites and other assets.

The Prototyping:

The mockup of the player

To start, I want immediately organized my player game object by having one parent game object and one child object. The parent game object will be the game object which will house all of the main components such as player movement script, rigidbody and also colliders. The child game object will be focused on the sprite and animation of the player.

TLDR: The player will be divided into two parts:
Main body = Rigidbody | Movement scripts | Colliders | Player Input
Child body = Sprite | Animation

This setup will allow me to swap in and out the character asset quickly without affect the scripts and other components that are crucial for the player.

Unity New Input System:

Since one of the goals was to create the game using Unity’s new Input System, we first need to set that up before we can continue scripting the player. Begin by downloading the Input System from the Package Manager and installing it.

Then in the projects tab, we are going to right click and create an New Input Actions.

Once you open up the new Input Actions, we are going to create a new Input Map called “Player Movement” along with the actions “Movement”, “Jump” and “Attack”.

For the assign Actions I am going to first setup the Keyboard inputs first, but later on, we can add in touch and also controller support. We then need to click the “Save Asset” button to confirm all our settings. Finally to make sure that the Input Actions are accessible via C# script, we need to generate the C# Class by selecting the Input Actions and checking the box within the Inspector.

To finish the setup for the New Input Controls, we need to add the Player Input component to the Player Parent game object. The Player Input will allow use to sync the settings we put into the Action Maps to the Player Movement Script that we are going to create in the next step.

This Component is assign to the parent of the Player Game Object.

Scripting the Player:

To begin I started by creating an new Player Movement C# script and attached it to the Parent object of the player. Inside the script I am first going to create some local variables that will be Serialized so I can add or change then within the Unity Inspector.

Even thought there are some variables that won’t be required during the prototype testing, I still decided to add them in. The main importance right now is to get the prototype player to move left and right and also jump.

Setting Up Player Movement:

I created a public method called “Move” with can callback context. This is because I am using the Player Input component on my player and I will manually assign the move function to the Action Map.

Within the public method I used an private local variable called _horizontal to contain the Read Value of the Callback. This info will allow me to know if I am positive 1 (facing and moving right) or negative 1 (facing and moving left).
Then by using the private variable a Vector 3 “_direction” and assigning a new Vector3 that has the _horizontal info I am able to tell the player to face either right or left.
The debug Log is going to also tell me in real time if I am positive or negative 1.
The IF statement that I have setup here is to allow my future setup when my Player becomes a 2D flat image. This statement allows it so that my player can flip 180 and back without any distortion.

To finally apply force and move the player in the update method we are going to use the Rigidbody Velocity and apply a new Vector2.

Since this is in the update method, it will occur whenever we press a button.

Setting Up Player Jump:

The player jump is going to require some more setup since we are going to require a “Ground Check” before the player can actually jump. The Ground Check as the name suggest is going to check whenever the player is grounded. If the player isn’t grounded then the player shouldn’t be able to jump even if the button has been pressed.

Since we are going to working with 2D assets within a 3D environment, we can’t use 2D ground checks. Instead we are going to use a Sphere with the Physics Check Sphere function. I start by creating a private method called “Ground Check”. Inside this method I am going to create an IF and ELSE statement. IF the statement is true, then the local variable is Grounded will be set to true, else it will be defaulted and set to false.

The IF statement is going to check for the Physics Check Sphere, which is positioned at the center of the transform (aka the player) position. The “Sphere Distance” is the local variable which we can set in the inspector. It is the diameter of the sphere. Finally the Floor Layer Mask is the layer settings which all platforms are attached too. If the object the player is on isn’t the identified layer mask, then the player can not jump.
Since the check sphere is going to be invisible we are going to create another method called “On Draw Gizmos”. With the Draw Sphere we should be able to visualize the sphere within the scene.

The Draw Gizmo in effect, we can see how big the sphere is around the player

To make the player physically jump up in the air we are going to do another public method which has another Callback Context. In the public method which we labeled as “Jump” we are going to create an IF statement checking for two things. If the context(aka button) has been pressed/performed and the player is Grounded, then we can Jump.
We can jump the player by using Rigidbody velocity and adding in a new Vector2 with an modified X value.

We are also going do another modification towards our jump function which is allowing the player to “Tap” the jump button and have a shorter jump height. This function is common in various 2D side scroller action game such as the famous Mario Brothers.
To create the tap function we are going to use the Unity Input System’s Cancelled feature. This means that whenever the button is tapped and not held long than a set duration, it will be treated as an half jump. To prevent this from being abused and having an endless of mini taps which results in the player air jumping, we are going to create an CD system for the cancelled jump.

This coroutine is setting the bool to true so the jump can not occur then after 0.5 seconds it will automatically set it back to false so the jump can happen again.

We need to make sure that the coroutine is going to be active, so we star the coroutine in the cancelled.

Applying the function to the Player:

Back in Unity we are finally going to apply all these moving function, if you haven’t already we are going to drag the Player movement script into the player. There we can drag and drop the required components into the slots and also add in the different values such as speed, jump power and rotation speed.

Next we are going to drag the Action Map from the New Input System into the player input “Actions” and select the default Map to the “Player Movement”

In the Events > Player Movement we have the preset Action Maps of Movement / Jump / Attack. We are going to link these Action Maps to the public methods which we created from the Player Movement script.

With these actions link to the corresponding scripts we can test the game out to see that the capsule does move left and right along with jump.



Simon Truong

A Designer, an Illustrator and a massive tech geek aspiring to become a professional Unity Developer.