Wall Jump Pushback

Godot Version

4.2.1

Question

I’m really new to Godot and I don’t know coding all too well. I’ve tried to implement wall jumping by following different tutorials, but I get stuck with the same problem every time, which is the pusback from jumping. From reading comments I find that it has something to do with my move_and_slide which resets my velocity.x or something. I don’t want to rebuilt my whole script but also somehow fix the pushback. Is there something I can do in my situation?

extends CharacterBody2D


const SPEED = 450.0
const JUMP_VELOCITY = -1020.0
const wall_jump = 1000
@onready var sprite_2d = $Sprite2D

const wall_friction = 500
var is_wall_sliding = false

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

var facing = null


func _physics_process(delta):
	if Input.is_action_pressed("left"):
		facing = 0
	if Input.is_action_pressed("right"):
		facing = 1
	
	if is_on_floor() and velocity.y == 0:
		if (velocity.x > 0.1):
			sprite_2d.animation = "run"
		elif (velocity.x < 0):
			sprite_2d.animation = "run-left"
		elif velocity.x == 0:
			if facing == 0:
				sprite_2d.animation = "idle-left"
			else:
				sprite_2d.animation = "idle"
	elif velocity.y > 0:
		if facing == 0:
			sprite_2d.animation = "fall-left"
		else:
			sprite_2d.animation = "fall"
	else:
		if facing == 0:
			sprite_2d.animation = "jump-left"
		else:
			sprite_2d.animation = "jump"
	
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta
	
	if Input.is_action_just_pressed("jump"):
		if is_on_floor():
			velocity.y = JUMP_VELOCITY
		if nextToRightWall() and Input.is_action_pressed("right"):
			velocity.y = JUMP_VELOCITY
			velocity.x = -wall_jump
		if nextToLeftWall() and Input.is_action_pressed("left"):
			velocity.y = JUMP_VELOCITY
			velocity.x = wall_jump
	
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, 36)
	
	move_and_slide()
	wall_slide(delta)

func nextToWall():
	return nextToRightWall() or nextToLeftWall()
	
func nextToRightWall():
	return $RightWall.is_colliding()
	
func nextToLeftWall():
	return $LeftWall.is_colliding()

func wall_slide(delta):
	if is_on_wall() and !is_on_floor():
		if Input.is_action_pressed("left") or Input.is_action_pressed("right"):
			is_wall_sliding = true
		else:
			is_wall_sliding = false
	else:
		is_wall_sliding = false
	
	if is_wall_sliding:
		velocity.y += (wall_friction * delta)
		velocity.y = min(velocity.y, wall_friction)

The problem is, that velocity.x is set to direction * SPEED after the wall jump, which overrides the wall jump. You need to decide, how the player is supposed to move after the wall jump. I can suggest two simple solutions.

  • Disable the movement along the x-axis for a while after the wall jump.

  • Add acceleration to the movement.

var direction = Input.get_axis("left", "right")
velocity.x = move_toward(velocity.x, direction * SPEED, 36.0)

That makes a lot of sense thank you, the pushback now works. But the change made to velocity.x now makes my character never slow down.

I’m trying to figure out how I can keep velocity.x = direction * SPEED at least for walking movement or an alternative that gives the same effect, but also not interfering with wall jump.

forget what I said, it worked to just replace velocity.x = direction * SPEED with velocity.x = move_toward(velocity.x, direction * SPEED, 36.0)

var direction = Input.get_axis("left", "right")
if direction:
	velocity.x = move_toward(velocity.x, direction * SPEED, 36.0)
else:
	velocity.x = move_toward(velocity.x, 0, 36)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.