The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

+1 vote

I'm trying to implement a wall jump in my platformer. When testing, I noticed a strange issue: the character would wall jump, then stop movement on the x-axis - horizontal movement that is.
Took me a few days to figure out the issue: when the variable which checked if the wall jump has occurred nullified, the code would check for horizontal movement, and as no movement buttons are pressed it would reset velocity to 0.
Here's the relevant code:

extends KinematicBody2D

const Gravity = Vector2(0, 400.0)
const WalkSpeed = 150
const WallJumpVelocity = Vector2(150, -100)

onready var WallJumpTimer = get_node("WallJumpTimer")
var JumpVelocity = -250.0
var WallJump = false
var Jumped = false
var velocity = Vector2()

signal WallJumpSignal

func get_input():
 if WallJump == false:
    if Input.is_action_pressed("Left"):
        velocity.x = -WalkSpeed
        get_node("AnimatedSprite").set_flip_h(true)

    elif Input.is_action_pressed("Right"):
        velocity.x = WalkSpeed
        get_node("AnimatedSprite").set_flip_h(false)
    else:
        velocity.x = 0

if is_on_wall():
    emit_signal("WallJumpSignal")

if is_on_floor():
    WallJump = false


func _physics_process(delta):
 get_input()
 velocity.y += delta * Gravity.y
 velocity = move_and_slide(velocity, Vector2(0, -1))

func _on_Character_WallJumpSignal():
 var WallDirection = get_which_wall_collided()
 if Input.is_action_just_pressed("Up"):
    WallJump = true

    #Jumped = true
    WallJumpTimer.start()

    if WallDirection == "left":
        velocity = WallJumpVelocity
        get_node("AnimatedSprite").set_flip_h(false)

    if WallDirection == "right":
        velocity.y = WallJumpVelocity.y
        velocity.x = -WallJumpVelocity.x
        get_node("AnimatedSprite").set_flip_h(true)


func _on_WallJumpTimer_timeout():
 WallJump = false

Sorry, my code is a mess. I'm a relatively new developer.
Can anyone please help me with this issue? Been trying to solve it for a few days now.

Godot version 3.2.3
in Engine by (13 points)

1 Answer

+1 vote

Honestly, I don't know what the issue is, but you seem to be making wall-jumping more complicated than it needs to be. This video shows a nice way to do it:
https://m.youtube.com/watch?v=mNTPh3Lz6zM&feature=youtu.be
Also, it seems in your code that you're using a timer for the wall jump, which seems unnecessary. If you want more help on wall jumping, I can help as I've done it before, but honestly, I can't really tell what the problem is just looking at your code.

by (599 points)

Thank you for your answer.

I already figured out the problem: get_input() checks if WallJump == false to execute. When the timer runs out (last line) it resets the variable to false. Then the input function checks if it's false at the next delta, and when no buttons are pressed it resets velocity.x to zero.
The code I pieced here is made of many different parts and suggestions from many different sources, so it makes sense it's overcomplicated.
The video is nice, but it concentrates on wall slide which is not something I think I want in my game. Besides, their wall jump jumps directly up with no horizontal movement, which could work I guess? but it's not quite what I want.

I want the player to move at 45 degrees after wall-jumping, and at the peak just fall down, if no other actions are taken. That's why I enabled the timer, so the jump is forced and controls are enabled a bit later.

Help would be very appreciated

This is what I use. You would of course have to change some values, but I think it would work. I just put it into the physics process.

func wall_jump():
        if walled == true:
            match sprite.flip_h:
                true:
                    if Input.is_action_just_pressed("jump"):
                        velocity.y = -jump_force 
                        velocity.x = jump_force
                false:
                    if Input.is_action_just_pressed("jump"):
                        velocity.y = -jump_force
                        velocity.x = -push_force

It has no sliding, pushes you off at 45 degrees without a timer, and is pretty simple. I hope it works for you, if not, I can continue to try and help you get your wall jump exactly how you want it.

Thank you again for your comment.

I think that'll work for me, at least for now. Maybe I'm just trying to get too fancy with my first projects. I'll use your piece of code for now, and maybe later on, when I get more experience and knowledge of GDScript, I'll try again to make it just like I want.

Thank you for helping me out! I really really appreciate that.

Yup! I’m sorry you couldn’t get wall jumping how you wanted, but I’m glad I could help!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.