Help with implementing a wall jump

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By raskolnikov

While trying to add a wall jump into my game I ran into an issue, the player can just spam jump against a wall and climb up the wall. The two solutions I found for this issue are to disable player input or make a wall jump have horizontal movement too. I’ve decided I’d much rather have the latter option, but have realised that changing my velocity.x in my code doesn’t move the player at all (although it does for basic walking and moving). I’m completely new to Godot and this is my first project so I’m sorry if this is some basic oversight, but I haven’t been able to figure it out on my own. Thanks for help in advance, here’s the code:

extends KinematicBody2D

export (int) var speed = 500
export (int) var jump_speed = 800
export (int) var gravity = 1500

var velocity = Vector2()
var can_jump = true
var jump_pressed = false
const WALL_SLIDE_ACCELERATION = 10
const MAX_WALL_SLIDE_SPEED = 120
const MAX_GRAVITY = 3000

export (float, 0, 1.0) var friction = 0.1
export (float, 0, 1.0) var acceleration = 0.5

func get_input():
	var dir = 0
	if Input.is_action_pressed("walk_right"):
		dir += 1
	if Input.is_action_pressed("walk_left"):
		dir -= 1
	if dir != 0:
		velocity.x = lerp(velocity.x, dir * speed, acceleration)
	else:
		velocity.x = lerp(velocity.x, 0, friction)
	velocity.x = 0
	if Input.is_action_pressed("walk_right"):
		velocity.x += speed
	if Input.is_action_pressed("walk_left"):
		velocity.x -= speed
	if Input.is_action_just_pressed("restart"):
		get_tree().reload_current_scene()

func _physics_process(delta):
	if is_on_floor():
		can_jump = true
	get_input()
	velocity = move_and_slide(velocity, Vector2.UP)
	if Input.is_action_just_pressed("jump"):
		jump_pressed = true
		rememberJump()
		coyoteTime()
		if can_jump == true:
			velocity.y = -jump_speed
			if is_on_wall() && Input.is_action_pressed("walk_right"):
				pass # <--------------
			elif is_on_wall() && Input.is_action_pressed("walk_left"):
				print("check") # <----------- check is printed, so
                                               # the problem must be with velocity.x
                                               # any value I add to it  here doesn't
                                               # effect the player at all
	if is_on_wall() && (Input.is_action_pressed("walk_right") || Input.is_action_pressed("walk_left")):
		can_jump = true
		if velocity.y >= 0:
			velocity.y = min(velocity.y + WALL_SLIDE_ACCELERATION, MAX_WALL_SLIDE_SPEED)
		else:
			velocity.y += gravity * delta
	else:
		velocity.y += gravity * delta
			
func hit():
	get_tree().reload_current_scene()
	
func bounce():
	velocity.y = -jump_speed
	
func coyoteTime():
	yield(get_tree().create_timer(.1), "timeout")
	can_jump = false
	
func rememberJump():
	yield(get_tree().create_timer(.1), "timeout")
	jump_pressed = false
:bust_in_silhouette: Reply From: Swander

Hey, congratulations with starting your game dev journey with Godot!
I believe i found the culprit in your code:

  1. You should initialise velocity vector at the start of your script (var velocity = Vector2(0,0))

  2. In you get_input() function dispose of line velocity.x = 0 thats what causing the ruckus

After those modification you would probably find your character behaviour no so pleasing. And that’s why i would strongly encourage you to take a look at free learning resources provided by other members of the community! The wall jump is a quite popular action in many platformers and is covered in a good ammount of tutorials on Godot and GDScript.
Cheers!

  1. The velocity vector is initiliased you must have missed it
  2. I removed velocity.x = 0, but it just made me go really fast and the issue remained
    Thanks anyway, I did write this with help of tutorials, but I try to figure things out on my own before copying. I’ll probably redo the script if I don’t figure how to fix this though.

raskolnikov | 2021-06-13 18:02

Oh, yeah, I overlooked vector initialisation
Have you tried using bigger velocity.x values to test? Because of the quirks of current implementation a value like velocity.x = -5000 was used by me to test the suggested solution.

Alternatively you could try replacing your “lerp()” functions that you use to cahnge velocity.x to “move_toward()” function

Swander | 2021-06-13 18:32

I’ve already tried using huge values to test and it didn’t change anything
I’ll try replacing the lerp function, but am not able to access my pc atm, thanks.

raskolnikov | 2021-06-13 18:42