Jump Buffer won't work properly

Godot Version

v4.4.1.stable.official [49a5bc7b6]

Question

Hello! I’m working on a game of mine, and I’ve implemented Jump Buffer and Coyote Jump, only my Jump Buffer won’t work properly. Instead of jumping the full height when you Jump Buffer, it only applies a fraction of the height than if you normally jump, almost like it’s bouncing. I am using a RigidBody3D for the player, here is it’s code:

extends RigidBody3D

@export var maxSpeed : float = 10000.0
@export var acceleration: float = 10000.0
@export var dashForce: float = 500000.0
@export var wallJumpForceBack: float = 4000.0
@export var wallJumpForceUp: float = 0.8
@export var jumpForce: float = 2000.0
@export var dashMaxCount: int = 2
@export var wallJumpMaxCount: int = 4

@onready var cam: Camera3D = $Camera
@onready var groundDetection: Area3D = $"Ground Detection"
@onready var wallDetection: RayCast3D = $"Wall Detection"
@onready var jumpBuffer = $"Jump Buffer"
@onready var coyoteJump = $"Coyote Jump"

var inputCtrls: Vector2 = Vector2.ZERO
var canJumpBuffer: bool = false
var canCoyoteJump: bool = false
var dashCount: int = 0
var wallJumpCount: int = 0
var onFloor: bool

func _physics_process(delta):
	
	onFloor = groundDetection.canJump

	# Movement
	inputCtrls = Vector2(Input.get_axis("left", "right"), Input.get_axis("forward", "backward"))
	
	# Dash
	if Input.is_action_just_pressed("dash") and dashCount < dashMaxCount:
		apply_central_force(-cam.global_basis.z.normalized() * dashForce * delta)
		dashCount += 1
		print(dashCount)
		
	var direction = (cam.global_basis * Vector3(inputCtrls.x, 0, inputCtrls.y)).normalized()
	
	direction.y = 0
	
	apply_central_force(direction * acceleration * delta)
	apply_central_force(-Vector3(linear_velocity.x, 0, linear_velocity.z).normalized() * 2500 * delta)
	
	# Jump
	
	if Input.is_action_pressed("jump"):
		if !canJumpBuffer:
			canJumpBuffer = true
	
	if canCoyoteJump:
		canCoyoteJump = false
		if linear_velocity.y < 0 and !onFloor:
			coyoteJump.start()
			canCoyoteJump = false
	
	if onFloor:
		canCoyoteJump = true
	
	if canJumpBuffer: 
		jumpBuffer.start()
		
	if Input.is_action_pressed("jump") or (!jumpBuffer.is_stopped() and onFloor):	
		if !coyoteJump.is_stopped() or onFloor:
			jump(jumpForce)

	if wallDetection.canWallJump and !onFloor:
		if Input.is_action_pressed("jump") and wallJumpCount < wallJumpMaxCount:
			apply_central_force(wallDetection.wallNormal * wallJumpForceBack)
			wallJumpCount += 1


func jump(jumpStrength: float):
	dashCount = 0
	wallJumpCount = 0
	apply_central_force(global_basis.y * jumpStrength)
	jumpBuffer.stop()
	coyoteJump.stop()
	canJumpBuffer = false
	canCoyoteJump = false

I’ll provide other details if needed! All help is appreciated!

Does the coyoteJump work as intended? For debug purpose remove it from code as well as the wallJump. Just remove all code that is not related to jump() for testing.

As i read your code you apply_central_force() in _physics_process() and then apply it again when you jump(). Maybe return some vector from jump(), add it to the general movement vector and only call apply_central_force() once at the end of _physic_process()

I guess the jumpBuffer and coyoteJump are Timers?

Hey! I somehow fixed my code by using an older version of it, I don’t know what changed, but if you’re curious, here’s what changed:

extends RigidBody3D

@export var maxSpeed : float = 10000.0
@export var acceleration: float = 10000.0
@export var dashForce: float = 500000.0
@export var wallJumpForceBack: float = 5000.0
@export var wallJumpForceUp: float = .45
@export var jumpForce: float = 6000.0
@export var dashMaxCount: int = 2
@export var wallJumpMaxCount: int = 4

@onready var cam: Camera3D = $Camera
@onready var groundDetection: Area3D = $"Ground Detection"
@onready var wallDetection: RayCast3D = $"Wall Detection"
@onready var jumpBuffer = $"Jump Buffer"
@onready var coyoteJump = $"Coyote Jump"

var inputCtrls: Vector2 = Vector2.ZERO
var canJumpBuffer: bool = false
var canCoyoteJump: bool = false
var dashCount: int = 0
var wallJumpCount: int = 0
var onFloor: bool

func _physics_process(delta):
	
	onFloor = groundDetection.canJump
	
	# Movement
	inputCtrls = Vector2(Input.get_axis("left", "right"), Input.get_axis("forward", "backward"))
	
	# Dash
	if Input.is_action_just_pressed("dash") and dashCount < dashMaxCount:
		apply_central_force(-cam.global_basis.z.normalized() * dashForce * delta)
		dashCount += 1
		
	var direction = (cam.global_basis * Vector3(inputCtrls.x, 0, inputCtrls.y)).normalized()
	
	direction.y = 0
	
	apply_central_force(direction * acceleration * delta)
	apply_central_force(-Vector3(linear_velocity.x, 0, linear_velocity.z).normalized() * 2500 * delta)
	
	# Jump
	
	if Input.is_action_just_pressed("jump"):
		if !canJumpBuffer:
			canJumpBuffer = true
	
	if canCoyoteJump:
		canCoyoteJump = false
		if linear_velocity.y < 0 and !onFloor:
			coyoteJump.start()
			canCoyoteJump = false
	
	
	if onFloor:
		canCoyoteJump = true
	
	if canJumpBuffer:
		jumpBuffer.start()
		canJumpBuffer = false
		
	if onFloor or coyoteJump.time_left > 0:	
		if jumpBuffer.time_left > 0 or Input.is_action_just_pressed("jump"):
			dashCount = 0
			wallJumpCount = 0
			apply_central_force(global_basis.y * jumpForce)
			jumpBuffer.stop()
			coyoteJump.stop()
			canJumpBuffer = false
			canCoyoteJump = false

	if wallDetection.canWallJump and !onFloor:
		if Input.is_action_just_pressed("jump") and wallJumpCount < wallJumpMaxCount:
			apply_central_force(wallDetection.wallNormal * wallJumpForceBack)
			wallJumpCount += 1