🤾Platform Movement Component

Platformer games are a convergence of numerous mechanics, making them an excellent learning opportunity for beginners

Getting started

This component is inherited from Godot Essentials Motion Component so it has the same functionality as it.

In this illustration, we aim to comprehensively unravel the mechanics inherent in a platformer. The GodotEssentialsPlatformerMovementComponent simplifies these intricacies, allowing us to center our focus on the fundamental concepts of our game.

⚠️ This component can only be used on CharacterBody2D node

Exported parameters

These parameters can be modified to achieve different behaviors. Below, we explain the purpose of each parameter and its impact on the component.

Gravity

  • Maximum fall velocity

  • Default gravity suspend duration

  • Defaul temporary gravity time

The gravity value that applies to the character is automatically calculated on the variable fall_gravity explained in the Jumpsection below.

The gravity inside the component can be inverted using the invert_gravity() function. This inversion affects the behavior of all functions based on its activation.

For instance, when gravity is reversed, the positive y-axis becomes the upper direction, and the negative y-axis becomes the lower direction. This change also updates the up_direction property.

The 'Maximum Fall Velocity' parameter defines the maximum velocity at which the character can fall. This affects the maximum value 'velocity.y' vector component can reach.

The Default gravity suspend duration is the default duration in seconds for which gravity remains suspended when the suspend_gravity_for_duration(duration: float) function is used.

The Default temporary gravity time is the duration, in seconds, for which gravity will be disabled when the change_gravity_temporary function is used.

Jump

We build the jump functionality inspired by the following videos:

This allows us to prototype a jumping mechanism according to what we are looking for without wasting a lot of time.

  • Jump height

  • Jump time to peak

  • Jump time to fall

The jump height is the height that our node can reach with a jump. This value is applied to internal calculations and affects the jump time to peak and jump time to fall.

The jump time to peak is the time the node takes to reach maximum height

The jump time to fall is the time the node takes to reach the floor again

Everytime one of this value are changed, a recalculation it's run on the following internal parameters:

  • jump velocity (calculated using jump height and time to peak)

  • jump gravity (calculated using jump height and time to peak)

  • fall gravity (calculated using jump height and time to fall)


  • Jump threshold

  • Allowed jumps

  • Height reduced by jump

  • jump_horizontal_boost

  • Coyote jump enabled

  • Coyote jump time window

The jump threshold defines a specific position threshold that governs whether the node is eligible to perform a jump. This occurs during descent as velocity.y incrementally builds. When the predefined value is almost reached and jump capability remains, this action can be taken.

The allowed jumps define the number of jumps the node can do, ideal for implementing double or triple jumps.

The height reduced by jump is used to reduce the effectiveness of the following jumps after the first one and improve the balance of the game mechanics. If you don't want to apply any reduction you can leave it at zero.

The jump horizontal boost provides an additional thrust along the x-axis during a jump if it is greater than zero

The coyote jump is based on the famous coyote from the Roadrunner cartoon series and allows you to jump in a defined time window when the node is falling. It is used to give a time margin to the player when he reaches the edge of a platform for example.

The coyote jump time window set the duration this functionality is active and you are allowed to jump while falling.

⚠️ During the time window when the 'coyote jump' is activated, the gravitational force is disabled.

Wall jump

  • Wall jump enabled

  • Wall jump force

  • Wall jump count as jump

  • Maximum permisible wall angle

The wall jump enabled releases the possibility of jumping when the node collides with a wall.

By default, the wall jump force is equal to the jump_height. However, if you wish to specify a different force for wall jumps, you can define that value here.

The wall jump count as jump when activated, counts this jump to the stack of allowed jumps, i.e. if the node has 2 allowed jumps, jumping to the wall and jumping again will exhaust its attempts.

The maximum permisible wall angle defines the the angle of inclination that the wall can have to be considered a wall, this is useful for cases in which the wall has a slight inclination and we want to use a wall jump.

Wall slide

  • Wall slide enabled

  • Override gravity on wall slide

  • Wall slide gravity

The wall slide enabled allows the node to slide when on a wall according to the value applied on wall slide gravity until it reaches the floor.

When Override gravity on wall slide is true, overrides the fall gravity and apply instead the wall_slide_gravity_value

In this state the node is able to do a wall jump so it can come in handy to allow the player to calculate distances or to glide to a certain point and jump.

Wall climb

  • Wall climb enabled

  • Disable gravity on wall climb

  • Wall climb speed (Up and Down)

  • Wall climb fatigue knockback

  • Time can climb

  • Time disabled when timeout

The wall climb enabled releases the possibility of climb when the node is on a wall. When this happens, the gravity and wall sliding are disabled to move freely in the y-axis.

The disable gravity on wall climb disables gravity so that climbing has no resistance when going up. This behaviour is activated by default

The wall climb speed defines the power of climb for the character, by default is the same value on both directions but can be changed and e.g. climb upwards at a slower speed than climbing downwards.

The wall climb fatigue knockback is the force applied when the time it can climb reachs the timeout to simulate fatigue. Uses the direction returned from get_wall_normal() as parameter to knockback() function. Set value to zero to to allow unlimited climbing

The time can climb defines a window time range where the character can climb and when it's finished the character can no longer climb the wall.

The time disabled when timeout defines the the period in which the wall climb will be disabled after the timeout has been reached. Set a value of zero to disable this behaviour.

Accessible Normal Variables

  • gravity_enabled: bool

  • is_inverted_gravity: bool

  • is_wall_sliding: bool

  • is_wall_climbing: sool

  • jump_queue: Array[Vector2]

  • suspend_gravity_timer: Timer

  • coyote_timer: Timer

  • wall_climb_timer: Timer

Upon entering the scene tree

  • Initializes the 'suspend gravity' timer for continuous use.

  • Connects to the 'jumped' signal.

  • Connects to the 'wall jumped' signal.

  • Connects to the 'wall climb started' signal

When the jump() function it's called and the character can jump the variables is_wall_sliding and is_wall_climbing are set to false

When the wall_jump() function it's called the variables facing_direction and last_faced_direction are set with the wall_normal vector value and lastly it emits the jumped signal

When the is_wall_climbing is set to true, disables the gravity if the exported variable disable_gravity_on_wall_climb is true and start the wall climb timer that simulates fatigue when it reaches timeout

Interactive functions

move()

Applies velocity to the character. This function activates the 'coyote jump' if it detects, based on the provided parameters, that the character was on the ground and is no longer.

accelerate_horizontally(direction: Vector2, delta: float = get_physics_process_delta_time())

Modifies the velocity.x value and apply acceleration if it's greater than zero. In this function, the direction vector is normalized, and the last_faced_direction is set to this value if it's not a Vector2.ZERO.

decelerate_horizontally(delta: float = get_physics_process_delta_time(), force_stop: bool = false)

Modifies the velocity.x If force_stop is true, the velocity.x is set to zero abruptly. If the friction value is greater than zero, deceleration is applied gradually using the FRICTION value.

get_gravity() -> float

Returns the current gravity force being applied, which is either jump_gravity or fall_gravity, depending on the sign of velocity.y, taking into account whether gravity is inverted.

apply_gravity(delta: float = get_physics_process_delta_time())

If gravity_enabled is set to true, this function applies the value obtained from the get_gravity() function to velocity.y. It also considers whether gravity is inverted and retrieves the fall_gravity value while taking into account the maximum fall velocity.

invert_gravity()

Inverts gravity based on the current value of gravity_enabled, switching it to the opposite state. This call emits the signal inverted_gravity(inverted: bool).

suspend_gravity_for_duration(duration: float)

Disables gravity for the specified duration in seconds and re-enables it when the timeout is reached.

is_withing_jump_threshold() -> bool

This function returns a boolean value indicating whether the character's position.y is within the valid threshold defined by the jump_threshold variable.

is_falling() -> bool

Returns whether, with the current component values, the character is falling. It performs the following checks:

  • Character is not on floor

  • The velocity.y is greater than zero (velocity.y less than zero when gravity is inverted)

  • Gravity is enabled

can_jump() -> bool

Returns whether, with the current component values, the character can jump. It performs the following checks:

  1. Checks if there are available jumps to perform.

  2. Checks if the 'Coyote jump' is active and enabled in the component.

  3. Checks if the character is within the jump threshold defined in the exported variable jump_velocity_threshold.

If there are available jumps, it always returns true. Otherwise, it performs the other two checks to confirm if the jump can be executed.

can_wall_jump() -> bool

Returns whether, with the current component values, the character can perform a wall jump. It essentially checks if the character is in contact with a wall and if there are available jumps to execute.

jump(height: float = jump_height, bypass: bool = false)

Applies a jump by modifying the velocity.y with the jump_velocity value. If bypass is set to true, the can_jump() function is not called to determine if the jump can be executed; it essentially forces a jump.

If the character can jump, the global origin position of the jump is also added to the jump_queue,and the jumped signal is emitted.

shorten_jump()

This function reduces thevelocity.y while an actual jump is in progress. Its primary use is to adjust the jump based on the player's input.

Here, you can observe an example in action:

if Input.is_action_just_pressed("jump"):
	godot_essentials_platformer_movement.jump()

if Input.is_action_just_released("jump"):
	godot_essentials_platformer_movement.shorten_jump()

wall_jump(direction: Vector2, height: float = jump_height)

This is a preliminary step before calling the jump() function, where a direction for the character's jump is specified. By default, wall_normal is used as the direction. if wall_jump_count_as_jump variable is set to true, this jump is is also added to the jump_queue

can_wall_slide() -> bool

Returns whether, with the current component values, the character can perform a wall slide. It essentially checks if the character is in contact with a wall and wall_slide_enabled is set to true.

wall_slide(delta: float = get_physics_process_delta_time())

Modify the value from velocity.y when the character is on the wall to simulate a sliding taking into account whether gravity is inverted. if override_gravity_on_wall_slide is set to true, applies the gravity value from wall_slide_gravity

can_wall_climb() -> bool

Returns whether, with the current component values, the character can perform a wall climb. It essentially checks if the character is in contact with a wall and wall_climb_enabled is set to true.

wall_climb(direction: Vector2)

This function receives a direction but only Vector2.UP and Vector2.DOWN trigger the climb movement. This also take into account whether gravity is inverted. When this function is being called, the gravity is disabled

reset_jump_queue()

This function is primarily used internally but can be manually called to initiate a jump reset. If the jump_queue variable is not empty, it emits the jumps_restarted signal.

Signals

  • gravity_changed(enabled: bool)

  • inverted_gravity(inverted: bool)

  • temporary_gravity_started(previous_gravity: float, current_gravity: float)

  • temporary_gravity_finished

  • jumped(position: Vector2)

  • wall_jumped(normal: Vector2, position: Vector2)

  • allowed_jumps_reached(jump_positions: Array[Vector2])

  • jumps_restarted

  • coyote_time_started

  • coyote_time_finished

  • wall_slide_started

  • wall_slide_finished

  • wall_climb_started

  • wall_climb_finished

Last updated