I'm trying to solve a lerp problem on my velocity, searched some stuff here and there, but found nothing that solved it. Can you help me?

extends CharacterBody2D

@export var _movespeed: float = 64.0
@export var _acceleration: float = 0.4 #Atraso na aceleração do personagem
@export var _friction: float = 0.8 #Desaceleração mais rápida

func _physics_process(delta: float) -> void:
func _move() -> void:
    var _direction:Vector2 = Vector2(
        Input.get_axis("move_left", "move_right"),
        Input.get_axis("move_up", "move_down")
    if _direction != Vector2.ZERO:
        velocity.x = lerp(velocity.x, (_direction.normalized() * _movespeed), _acceleration)
        velocity.y = lerp(velocity.y, (_direction.normalized() * _movespeed), _acceleration)

    velocity.x = lerp(velocity.x, (_direction.normalized() * _movespeed), _friction)
    velocity.y = lerp(velocity.y, (_direction.normalized() * _movespeed), _friction)
    velocity = (_direction.normalized() * _movespeed)

1 Answer 1


You're trying to lerp between a float (velocity.x) and a Vector2 (_direction). Try accessing the x and y params of the _direction Vector2 for lerping:

func _move() -> void:
    if _direction != Vector2.ZERO:
        velocity.x = lerp(velocity.x, (_direction.normalized().x * _movespeed), _acceleration)
        velocity.y = lerp(velocity.y, (_direction.normalized().y * _movespeed), _acceleration)

    velocity.x = lerp(velocity.x, (_direction.normalized().x * _movespeed), _friction) # Normalizing a ZERO Vector2?
    velocity.y = lerp(velocity.y, (_direction.normalized().y * _movespeed), _friction) # Normalizing a ZERO Vector2?
    velocity = (_direction.normalized() * _movespeed) # Normalizing a ZERO Vector2? + Overwrites previous changes to the velocity?

the Code below the return statement seems to be incorrect aswell as you're trying to normalize the _direction Vector2 which is a Vector2.ZERO at this point. I'm not sure how Godot handles that.

  • 2
    \$\begingroup\$ Why do the lerp in two steps, one per component, instead of all at once? e.g. velocity = lerp(velocity, _direction.normalized() * _movespeed, _acceleration) ? Godot treats normalizing a zero vector as a no-op, so the second batch of lerps is equivalent to velocity = velocity * (1 - _friction) and the last line just sets velocity to zero, so the previous lines are redundant. \$\endgroup\$
    – DMGregory
    Jul 12, 2023 at 12:11
  • \$\begingroup\$ Yep, when normalizing the velocity on last line, we get -1,0,1 based on direction, multiplied by 64.0 (frame movement speed), it will normalize the Zero Vector only when the character doesn't make any moves \$\endgroup\$ Jul 12, 2023 at 17:53
  • \$\begingroup\$ Also, thanks for correcting my syntax on lerp functions, I'm following a Godot tutorial to learn the basics, but the code of the instructor is kinda different, but it also works :( maybe it's a version difference \$\endgroup\$ Jul 12, 2023 at 17:54
  • \$\begingroup\$ While normalizing a zero vector gives you a zero vector... You might still want to check if it is approximately zero. Because then the small error will be blown up. In fact, it might give you something that is not normalized. See github.com/godotengine/godot/issues/74852 \$\endgroup\$
    – Theraot
    Jul 19, 2023 at 11:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .