I can't get the lerp function to work for my character

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Amateur.game.dev.

Please help, I’ve looked online and practically done exactly what others have said to do. I’m working on a 2D top-down RPG, so my character has 8-way movement. To make it look and feel smoother I wanted to add a lerp function, as I did last week on a platformer test project. But it did not work as expected (not at all). Here is my script:

var velocity = Vector2()
var speed = 50
func get_input():
    if Input.is_action_pressed("Forward"):
        velocity.y = -speed
    if Input.is_action_just_released("Forward"):
        velocity.y = lerp(velocity.y, 0, 0.1)
    else:
        pass
func _physics_process(delta):
    get_input()
    move_and_slide(velocity)

You’d expect the character to stop at least, but he just keeps on walking forward.
Any help is very much appreciated!

:bust_in_silhouette: Reply From: RandallCurtis

Input.is_action_just_released will only be true during the 1 frame that the action was released. Lerp should be called during every frame and also with delta to smooth properly. So your code would then be something like:

extends KinematicBody2D

var velocity = Vector2()
var speed = 50

func get_input(delta):
	if Input.is_action_pressed("Forward"):
		velocity.y = -speed
	else:
		velocity.y = lerp(velocity.y, 0, 10 * delta)

func _physics_process(delta):
	get_input(delta)
	velocity = move_and_slide(velocity)

Also remember to assign the return value from move_and_slide() back to ‘velocity’ so that slide collisions work as expected.

:bust_in_silhouette: Reply From: Ninfur

So what’s happening is that while you press “Forward”, the following code will run repeatedly, setting the velocity to -50.

if Input.is_action_pressed("Forward"):
    velocity.y = -speed

However, when “Forward” is released, the code inside the next if-statement is only going to run once, due to the “just_released”-part.

if Input.is_action_just_released("Forward"):
    velocity.y = lerp(velocity.y, 0, 0.1)

All lerp is doing is to move some value (velocity.y) closer to a target value (0) by a factor (0.1). That means, if lerp is called once when the velocity is set to -50, it will result in the velocity moving 10% closer to 0, in other words velocity will end up being -45.

In order to get the stopping effect you want, the lerp part must be run repeatedly until the target value has been reached.

One way of doing this would be to change

if Input.is_action_just_released("Forward"):

into

if not Input.is_action_pressed("Forward"):