Intro
This series is a collection of independent Godot scripts and mechanics. Whether you want to build something from scratch or dive into specific technical solutions, these modules are designed to be easily integrated into your projects.
Note: This article focuses specifically on the implementation of Jumping in Godot. To get the most out of it, you should already be comfortable navigating the Godot UI.
The Art of Jumping
You might wonder why I’m dedicating an entire article to jumping. I promise you’ll understand why by the end of it.
The naive approach to jumping in a game engine would be just simply adding an upwards jump-force to your player.
1 extends CharacterBody2D
2 @export var jump_velocity: float = 100.0
3
4 # naive jumping approach
5 func _physics_process(delta: float) -> void:
6 if Input.is_action_just_pressed(" jump"):
7 if is_on_floor():
8 velocity.y = jump_velocity
This results in a movement that follows a perfect parabola. However, if you look at popular games, you'll notice that most of them don't work that way. Instead, it often feels like the player reaches the peak quickly but falls back down even faster. And when implementing this naive way you might feel, that something is off. So how can you implement these physically incorrect jumps?
Implementation
Physics
First of all let's take a look at the physics behind jumping. Jumping is actually a constant linear acceleration which can be described with these really simple mathematical formulas.
- Velocity
Velocity over time ($t$) given a constant acceleration ($a$)
- Traveled distance
The displacement ($s$) over time with a constant acceleration ($a$)
Calculating custom gravity
To make the implementation easier, we need to rearrange these formulas. This allows us to simply plug in our desired values for time to peak, descent time, and maximum jump height.
Since we want to replace the gravity with our new custom gravity we need to isolate a in our second formula. This gives us the following formula.
Code
With the physics out of the way we can start with the fun part, by actually implementing the new gravity. first we add our variables to the script.
1 @export_group("Jumping")
2 @export var jump_height: float
3 @export var jump_time_to_peak: float
4 @export var jump_time_to_descent: float
Next, we need to create a function that returns our gravity based on the player's current velocity. When the player reaches the peak, the velocity changes direction. And we need to use a different value for $t²$
1 func get_custom_gravity() -> float:
2 # Falling down
3 if velocity.y > 0:
4 return (2.0 * jump_height) / (jump_time_to_descent**2)
5 # Jumping up
6 else:
7 return (2.0 * jump_height) / (jump_time_to_peak**2)
Finally, we tie this function together by calling it in physics_process when the jump button is pressed.
Note you need to define a "jump" action beforehand
1 func jump():
2 if is_on_floor():
3 # Since the y-axis in Godot is inverted (-1 is up), we multiply by -1
4 var jump_velocity = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
5 velocity.y = jump_velocity
6
7 func _physics_process(delta: float) -> void:
8 # add the downwards force to the player
9 velocity.y += get_custom_gravity() * delta
10
11 if Input.is_action_just_pressed(" jump"):
12 jump()
Now you can test it out in your own game or right now here in the Browser with this small Demo i built: open in new Tab