#lerp takes too long to finish

1 messages · Page 1 of 1 (latest)

plain haven
#

I am trying to make a smooth grid-based 3d movement(Legend of Grimrock 2 for the reference) and I am using lerp to set player's position but it has unpleasant delay at the end; Is there any way to make it more responsive

Here is my movement script

extends Node3D

const SPEED = 15.

var new_pos: Vector3 = Vector3.ZERO
var moving: bool = false

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
    var cellpos = %Map.map_to_local(Vector3i(0,0,0))
    position = cellpos
    new_pos = position


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
    if moving:
        position = position.lerp(new_pos, delta * SPEED)

    if position.is_equal_approx(new_pos):
        moving = false


func _input(event: InputEvent) -> void:
    handle_movement(event)


func handle_movement(event: InputEvent) -> void:
    if moving:
        return

    if event.is_action_pressed("forward"):
        new_pos = Vector3(position.x, position.y, position.z + %Map.cell_size.z)
    if event.is_action_pressed("backward"):
        new_pos = Vector3(position.x, position.y, position.z - %Map.cell_size.z)
    if event.is_action_pressed("left"):
        new_pos = Vector3(position.x + %Map.cell_size.x, position.y, position.z)
    if event.is_action_pressed("right"):
        new_pos = Vector3(position.x - %Map.cell_size.x, position.y, position.z)

    moving = true

%Map is a GridMap object

also attached the video which shows that movement is set to false with very big delay even so player has already stopped moving

valid magnet
#

You're using lerp wrong. Lerp is supposed to be used like start_pos.lerp(end_pos, percentage) where percentage is a value between 0 and 1 and it'll give you a position that is that much distance from start_pos to end_pos. For example using 0.5 as percentage will give you a point that is exactly halfway between them.

What you are doing is technically doable but it's not a clean and efficient solution. The moving variable remains true because the object is still moving, just extremely slowly, until it comes to a complete stop due to floating point accuracy

In your case I believe it'd be better to use tweens instead.

plain haven
valid magnet
plain haven