2.5D Platformer — Basic Controller #2
Move, Jump and Fall!

As all Platformers, moving and jumping are the most common features in a controller, and most important of all, it should feel good and fun to control. Having dealt with platformers before, both 2D and 3D, I have some tips that might help you make something interesting.
Setup
With just a Character Controller in any of your GameObjects is fine. Once you have your controllable character, I added a script where I’ll code the movement. And yes, I use the new Input System and so should you.

Moving
To begin coding, I know that to move the player at a constant speed I’ll need a reference to the Character Controller to access its Move() method, an input value from our Movement Action Input, a walk speed variable, and a value where the final Horizontal Speed is stored and used to move the controller.

The Character Controller reference will be assigned in the Editor’s Inspector. To obtain the Input values, I’ve created a new Action Input called Movement, and in the Player Input component, I use Unity Events and added the method below which will run when any of the WASD keys are pressed. Because the input values returned by the System are abstract, I need to specify the type of value the controller is receiving.


The Horizontal Speed is just the horizontal input value multiplied by the walk speed. And then, that value is used to move the controller. (Remember to multiply the velocity to Time.deltaTime to make the movement frame independent).


Falling
To fall down, it’s as easy as constantly adding the gravity acceleration to the Current Vertical Speed, clamping the max negative speed, and then applying that to the total velocity of the controller.
But, I found it to be snappier if the controller fell faster than it rises up (you’ll see when I get to jumping). So, I applied extra force only if the Current Vertical Velocity is lower than 0.


Jumping
As almost all jumping mechanics, to jump the controller will need to be on the ground, apply the jump force to the controller, and restrict the player from jumping again until the controller touches the ground.


To handle reseting the “jumped” boolean and adjusting some values to my liking, such as not instantly falling at the gravity velocity, I’ve declared a Grounded getter/setter. Every time the previous value doesn’t match the new one, an event is triggered.

What does “OnGroundStateChange” do? It’s an event that will invoke all suscribed methods to it. In this case, its suscribed to the method below.

And last, but not least, I’ve updated the VerticalMovement method to add gravity acceleration only when the controller isn’t on the ground.

End Result
