0 votes

I'm having some issues with move_and_slide function in a platformer game. For some reason, if character is standing on floor and is running into a wall, there's some upward motion that seems to come out of nowhere and is being applied every other frame.

Here's how it looks (notice movement vector printed every frame in the console):

https://youtu.be/lga0l3amuS8

Here's the code for movement:

extends KinematicBody2D

const SPEED = 50
const GRAVITY = 250
const JUMP_FORCE = -130
const JUMP_CUT = -80

#var can_attack = true
var motion = Vector2()
var last_frame_motion = Vector2()

func _physics_process(delta):
    update_motion(delta)

func _process(delta):
    update_animation(motion)    

func update_motion(delta):
    last_frame_motion = motion
    fall(delta)
    run()
    jump()
    jump_cut()
    motion = move_and_slide(motion, Vector2.UP)
    print(motion)

func update_animation(motion):
    $AnimatedSprite.update_anim(motion)

func fall(delta):
    motion.y += GRAVITY * delta
    motion.y = clamp(motion.y, -GRAVITY, +GRAVITY)

func jump():
    if Input.is_action_just_pressed("ui_up") and is_on_floor():
        motion.y = JUMP_FORCE

func jump_cut():
    if Input.is_action_just_released("ui_up") and motion.y < JUMP_CUT :
        motion.y = JUMP_CUT 

func run():
    if Input.is_action_pressed("ui_right") and not Input.is_action_pressed("ui_left"):
        motion.x = lerp(motion.x, SPEED, 0.1)
    elif Input.is_action_pressed("ui_left") and not Input.is_action_pressed("ui_right"):
        motion.x = lerp(motion.x, -SPEED, 0.1)  
    else:
        if last_frame_motion.y == 0:
            motion.x = lerp(motion.x, 0, 0.12)
            if motion.x > 0 and motion.x < 5:
                motion.x = 0            
            elif motion.x < 0 and motion.x > -5:
                motion.x = 0
        else:
            motion.x = lerp(motion.x, 0, 0.042)

I've even tried using move_and_slide_with_snap but had no success with it either.

Not sure what is the problem here

Godot version 3.2.3
in Engine by (12 points)

1 Answer

0 votes

Most likely to do with the fact you are calling fall() every frame without checking if you are actually falling. Make an if statement to check if you're falling within the fall function and it won't always run.

This video is great for player movement in a nice clean way:
https://www.youtube.com/watch?v=0713nlQxU7I

by (140 points)
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.