Wall jump Help title must be 15 characters

Godot Version

4.7

Question

I made a script that has wall sliding and wall jumping. When I wall jump, I want player to push away from the wall so you cant just spam jump repeatadly. Any help?

extends CharacterBody2D

@export var speed: float = 300.0
@export var jump_velocity: float = -400.0
@export var gravity: float = 980.0

# Wall mechanics variables
@export var wall_slide_gravity: float = 100.0
@export var wall_jump_velocity: Vector2 = Vector2(350.0, -400.0)

func _physics_process(delta: float) -> void:
	# Add gravity
	if not is_on_floor():
		if is_on_wall() and velocity.y > 0:
			# Apply reduced gravity for wall sliding
			velocity.y += wall_slide_gravity * delta
		else:
			# Apply normal gravity
			velocity.y += gravity * delta

	# Handle Jump
	if Input.is_action_just_pressed("jump"):
		if is_on_floor():
			velocity.y = jump_velocity
		elif is_on_wall_only():
			wall_jump()

	
	var direction := Input.get_axis("move_left", "move_right")
	
	if direction != 0:
		velocity.x = direction * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)

	move_and_slide()

func wall_jump() -> void:
	var wall_normal = get_wall_normal()
	velocity.x = wall_normal.x * wall_jump_velocity.x
	velocity.y = wall_jump_velocity.y

Your velocity.x is instantly overwritten by the input direction, you will have to change this to “push” the velocity towards the input instead of setting it directly. move_toward is good for this, but the else branch 1. isn’t needed, and 2. is frame-dependent and 3. way too strong to notice

You should make a new “acceleration” variable, for this value a good starting point may be 4x your speed

var direction := Input.get_axis("move_left", "move_right")
velocity.x = move_toward(velocity.x, direction * speed, acceleration * delta)

Thanks!

it didn’t work :frowning:

You will have to give more details than that, what does your new script look like after the changes? How does it not work?

I can still just spam jump and the player won’t push away/bounce away from the wall. Also the ground controls got messed up

The “push away” from the wall could be in the wrong direction, or much too low of a value. Try making your wall_jump_velocity.x much larger and/or negative.

How did the ground controls get messed up? You have to describe what you expect to happen versus what really happens, otherwise we’re left guessing. And of course posting the edited code would help too.

I increased wall_jump_velcocity.x but you can still spam. Also the ground controls messed up because when I pressed left or right then I stopped pressing them, the character kept moving that direction.

If you do get pushed away from the wall, but the force is not enough then you have a few options. You can increase the jump further, or you can reduce the acceleration value. Potentially lowering acceleration only if in the air. If you don’t get pushed away from the wall then try using a negative value.

They should still move for a little bit, it now accelerates down to zero. Unless your code has an error in it, you would have to post your new code.

You could disable player input for a short duration after the wall-jump:

var input_disabled_timer: float = 0

func _physics_process(delta: float) -> void:
	
	# Jump code omitted for brevity
	
	var direction := Input.get_axis("move_left", "move_right")
	
	input_disabled_timer -= delta
	
	if direction != 0 and input_disabled_timer <= 0:
		velocity.x = direction * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)

	move_and_slide()

func wall_jump() -> void:
	var wall_normal = get_wall_normal()
	velocity.x = wall_normal.x * wall_jump_velocity.x
	velocity.y = wall_jump_velocity.y
	input_disabled_timer = 0.1 # !! New !!

If you choose to implement something like this, you might also want to reset the timer when the player hits the ground, especially if you increase input_disabled_timer.