Need help to make jump buffering and coyote jumping

Godot Version

4.2.1

Question

I have watch some tutorials on Youtube to make a jump buffering and coyote jumping, but it dont work/my double jump stop working

Here’s my code :

extends CharacterBody2D

@export var speed = 150
@export var gravity = 20 
@export var jump_force = 300 
@export var down_speed = 700
@export var dash_speed = 450 
@export var superjump_speed = 500 


var dashing = false 
var can_dash = true

#max jump, dash, superjump
var jump_count = 0
var max_jumps = 2
var dash_count = 0
var max_dash = 1
var max_superjump = 1
var superjump_count = 0

func _physics_process(delta): 
	if !is_on_floor(): 
		velocity.y += gravity 
		if velocity.y > 500:
			velocity.y = 500 


#pour faire des petits saut
	if Input.is_action_just_released("jump") and velocity.y < 0:
		velocity.y = jump_force / 5


	if is_on_floor():
		jump_count = 0
		dash_count = 0
		superjump_count = 0

	if Input.is_action_just_pressed("jump"):
			if jump_count < max_jumps:
				jump_count += 1
				velocity.y = -jump_force



	if Input.is_action_pressed("move_down"): 
		velocity.y = down_speed


	var horizontal_direction = Input.get_axis("move_left","move_right") 
	velocity.x = speed * horizontal_direction 
	
	#if horizontal_direction != 0:
		#$AnimationPlayer.flip_h = (horizontal_direction == -1)
	
	#floor
	if is_on_floor() and horizontal_direction == 1:
		$AnimationPlayer.play("walk")
	if is_on_floor() and horizontal_direction == -1:
		$AnimationPlayer.play("walk")
	if is_on_floor() and horizontal_direction == 0:
		$AnimationPlayer.play("idle")


	#jump
	if !is_on_floor() and velocity.y < 0:
		$AnimationPlayer.play("jump")


	#fall
	if !is_on_floor() and velocity.y > 0 and horizontal_direction == 1:
		$AnimationPlayer.play("fall")
	if !is_on_floor() and velocity.y > 0 and horizontal_direction == -1:
		$AnimationPlayer.play("fall")
	if !is_on_floor() and velocity.y > 0 and horizontal_direction == 0:
		$AnimationPlayer.play("fall")

	else:
		if horizontal_direction != 0:
			$AnimationPlayer.flip_h = (horizontal_direction == -1)


	if horizontal_direction: 
		if dashing:
			velocity.x = dash_speed * horizontal_direction



	if Input.is_action_just_pressed("dash") and can_dash: 
		if dash_count < max_dash:
			dash_count += 1
			dashing = true
			can_dash = false
			$dash_timer.start()
			$dash_again_timer.start()




	if Input.is_action_just_pressed("super_jump"):
		if superjump_count < max_superjump:
			superjump_count += 1
			velocity.y = -superjump_speed



	move_and_slide() 

#stop dashing
func _on_dash_timer_timeout():
	dashing = false
func _on_dash_again_timer_timeout():
	can_dash = true
	

	
	
	print(velocity)

I just tested your code on an empty project, with a player and a platform and the double jump works fine. What exactly is the problem? how is it not working?

On the other hand, coyote jumping is easy to implement, just extend the CollisionShape2D beyond the visual sprite itself (pink for the sprite, green for the CollisionShape2D) that should do the trick.

image

thx for your answer !

yeah the double jump work, it’s when I try to add Coyote Jumping. Because in the Youtube video I watch they don’t use your idea with the collisionshape2D. Instead they do it in the player scripts and with a timer.
But when I do it, it break my double jump because of this :

if Input.is_action_just_pressed("jump"):
			if jump_count < max_jumps:
				jump_count += 1
				velocity.y = -jump_force

because instead of if jump_count < max_jumps: they use if is_on_floor():
because they don’t have a double jump

Btw nice idea ! But didnt it have a probleme ? I will not be able to go close to a wall, no ?

Oh, I get it. You want to keep the CollisionShape as it is, but if the character falls, to have a few milliseconds of “coyote time” to be able to jump, is that correct?

How about this. You let them jump if they have touched the ground in the last 200 milliseconds (or 300, or 100, you can change that to whatever you want). Instead of using a timer, you can check the time since it was last on_floor using Time.get_ticks_msec(). It’s more precise than a Timer.

First, add a variable called last_time_on_floor:

#max jump, dash, superjump
var jump_count = 0
var max_jumps = 2
var dash_count = 0
var max_dash = 1
var max_superjump = 1
var superjump_count = 0
var last_time_on_floor = 0

Then only let them jump if less than 200ms have passed since they last touched the ground (or if jump_count==1, you always let them do the double jump).

	if is_on_floor():
		jump_count = 0
		dash_count = 0
		superjump_count = 0
		last_time_on_floor = Time.get_ticks_msec()

	if Input.is_action_just_pressed("jump"):
			var current_time = Time.get_ticks_msec()
			if current_time - last_time_on_floor < 200 or jump_count == 1:
				if jump_count < max_jumps:
					jump_count += 1
					velocity.y = -jump_force

I just tested it with your code and it works, check the video. In fact, if more than 200ms pass I can’t “coyote jump” and I just fall to the abyss.

2 Likes

thx ! That work perfectly, and now I can try adding jump buffering (because in youtube video they use the part of code they use in coyote jumping i think)