# Platform Movement Component

## Getting started

This component is inherited from [Godot Essentials Motion Component](/addons-documentation/components/godot-essentials-motion-component.md) 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.

:warning: *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 [#jump](#jump "mention")section 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.&#x20;

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` ](https://docs.godotengine.org/en/stable/classes/class_characterbody3d.html#class-characterbody3d-property-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:

* [Making a jump you can actually use in godot](https://www.youtube.com/watch?v=IOe1aGY6hXA)&#x20;
* [Math for Game Programmers: Building a Better Jump](< https://www.youtube.com/watch?v=hG9SzQxaCm8\&t=0s>)

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.

:warning: *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.&#x20;

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&#x20;

## 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_velocit`y 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 the`velocity.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:

```python
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)*&#x20;
* *inverted\_gravity(inverted: bool)*&#x20;
* *temporary\_gravity\_started(previous\_gravity: float, current\_gravity: float)*&#x20;
* *temporary\_gravity\_finished*
* *jumped(position: Vector2)*&#x20;
* *wall\_jumped(normal: Vector2, position: Vector2)*&#x20;
* *allowed\_jumps\_reached(jump\_positions: Array\[Vector2])*&#x20;
* *jumps\_restarted*&#x20;
* *coyote\_time\_started*&#x20;
* *coyote\_time\_finished*&#x20;
* *wall\_slide\_started*
* *wall\_slide\_finished*&#x20;
* *wall\_climb\_started*&#x20;
* *wall\_climb\_finished*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://godot-essentials.gitbook.io/addons-documentation/components/godot-essentials-motion-component/platform-movement-component.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
