0 votes

Originally posted to discord:
Could someone give me some insight as to what might be causing this bug:
I'm trying to implement a double jump for my character. If he's on the ground and he jumps then he gets another one, if he walks off a ledge or the ground disappears beneath he still has one. Basically, he has one midair jump that resets when he touches the ground.

Problem: occasionally (it seems to be randomly) when i jump from the ground my midair jump disappears and i cannot jump. Also seems to only happen when moving left or right while jumping.

So my logic is: keep track of the number of midair jumps you have left (it's 1 for this case). if you're currently grounded and you press jump, ur character jumps but no values change. If you press jump and you're not grounded and you have more than 0 midair jumps left, it subtracts 1 from the midair jumps, and ur character jumps. Otherwise, you're character doesn't jump and no values get updated. On each update of _physics_process() i check whether or not you're grounded at the very start, and store it in a variable and then use that for everything else. Then i check for jump input, and then i check for horizontal movement inputs. move_and_slide() is the final line of _physics_process() if that makes any difference. Im guessing it has something to do with how is_on_floor() only updates when move_and_slide() gets called? I have no idea though and ive been stuck for a few hours.

extends KinematicBody2D
export var xSpeed = 500;
export var gravity = 1000;
export var jumpSpeed = 600;

var motion = Vector2(0,0);
const UP = Vector2(0,-1);
var midairJumpsLeft = 1;
var grounded = true;

func _physics_process(delta): #Update -------------

    applyGravity(delta);
    checkJump();
    horizontalMove();

func _process(delta): 
    print(midairJumpsLeft);
#-----------------------------------

func applyGravity(delta):
    if (is_on_floor()):
        grounded = true;
        midairJumpsLeft = 1; #also reset jumps when grounded
        motion.y = 0;
    else: 
        grounded = false;
        motion.y += gravity*delta;

func checkJump():
    if (Input.is_action_just_pressed("player_jump")):
        if (not grounded) && midairJumpsLeft > 0:
            midairJumpsLeft = 0;
            motion.y = -jumpSpeed;
        elif grounded:
            midairJumpsLeft = 1;
            motion.y = -jumpSpeed;

func horizontalMove():
    motion.x = 0;
    if (Input.is_action_pressed("player_left")):
        motion.x += -xSpeed;
    if (Input.is_action_pressed("player_right")):
        motion.x += xSpeed;
    move_and_slide(motion, UP);

Also I apologize for the unnecessary semicolons and parentheses, it's just what im used to at this point.

EDIT: Link to video of bug

https://www.youtube.com/watch?v=uiE9wUvbuAQ

asked Jul 2, 2019 in Engine by Henry Liu (23 points)

2 Answers

0 votes
Best answer

I did actually find a reddit comment from a year ago which solved all my issues.
First of all the perpetrator is

if is_on_floor():
    velocity.y = 0

This causes the weird interaction where grounded rapidly switches between true and false.

However, removing this statement will make it so that you continue to generate speed from gravity even as you stand on solid ground. To solve this, instead of just calling move_and_slide(), I needed to set velocity = move_and_slide() which did all the calculations for me.

answered Jul 2, 2019 by Henry Liu (23 points)
0 votes

Try calling horizontal_move() before applyGravity(). is_on_floor() is only updated after move_and_slide() is called.

answered Jul 2, 2019 by Dlean Jeans (3,873 points)

I'd already tried that. It doesn't work.

I did actually find a reddit comment from a year ago which solved all my issues.
First of all the perpetrator is

if is_on_floor():
    velocity.y = 0

This causes the weird interaction where grounded rapidly switches between true and false.

However, removing this statement will make it so that you continue to generate speed from gravity even as you stand on solid ground. To solve this, instead of just calling move_and_slide(), I needed to set velocity = move_and_slide() which did all the calculations for me.

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 How to use this Q&A? before posting your first questions.