+3 votes

Hi, I'm making a little platformer prototype, and I'm using the 'moveandslidewithsnap()' function, and it's doing exactly what I want, but when going down a slope, sometimes it decides to stop snapping, and jump up into the air. I'm not sure what's the issue. Here's my code :

extends KinematicBody2D

var max_speed : float = 500
var acceleration : float = 10
var gravity : float = 20

var jump_force : float = 600
var jump_stop : float = 10

#this acts as a one dimentional vector
var input_direction : float
var velocity : Vector2


func _input_loop():

    var move_left = Input.get_action_strength("move_left")
    var move_right = Input.get_action_strength("move_right")

    input_direction = move_right - move_left


func _movement_loop(i_dir):

    velocity.x = move_toward(velocity.x, i_dir * max_speed, acceleration)


func _v_movement():

    #jump
    if is_on_floor():
        if Input.is_action_just_pressed("jump"):
            velocity.y = -jump_force
    else:
        if Input.is_action_just_released("jump"):
            if velocity.y < jump_stop:
                velocity.y = jump_stop

    #gravity
    if not is_on_floor():
        velocity.y += gravity


func _physics_process(delta):
    _input_loop()
    _movement_loop(input_direction)
    _v_movement()

    velocity = move_and_slide_with_snap(velocity, Vector2.DOWN * 10, Vector2.UP)
Godot version 3.2.3
in Engine by (15 points)

Tried it and noticed the same. It occurs at corners where slope steepens. I think the collider hits the corner while already falling, thus changing the movement vector. I'm not sure how to fix it though. Maybe somebody who has more experience with platformer controllers can?

I also tried with 3.4 beta as they made some improvements to move_and_slide functions, but no difference in this case.

1 Answer

0 votes

It seems that the snap vector isn't big enough. When I set it to 10 times more, the problem didn't occur anymore in my test level. As a side effect, jumping also didn't work, but that was easy to work around by removing the snap vector upon jumping.

var snap_vector = Vector2.DOWN * 100 if not Input.is_action_just_pressed("jump") else Vector2.ZERO
velocity = move_and_slide_with_snap(velocity, snap_vector, Vector2.UP)

You may need to further tweak it for your use case.

by (382 points)

Hi, I was trying to implement your solution, and it seemed to be working, however when the character goes over a cliff, I want him to fly off without snapping down to the bottom, and this is the case, however he still jumps.

Have you tried different values? Maybe 100 is an overkill, try 50 next.

Yes I did, and I do think that 100 is overkill, because If the character walks off a clif, and the floor is within 100px of the character, then it snaps all the way down, however if it isn't and the character flys off the edge, it leaps up into the air. I tried to do a manual solution using a raycast, and a collision shape that only covers the top section of the character, however it's a bit buggy, and it doesn't work with moving platforms (which the moveandslidewithsnapping() function fixes) so I'm just a bit lost. :(

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.
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 webmaster@godotengine.org with your username.