Player stopping mid air

Godot Version

`extends CharacterBody3D

var speed
const WALK_SPEED = 4.0
const SPRINT_SPEED = 7.0
const JUMP_VELOCITY = 4.5
const SENSITIVITY = 0.003

@onready var head = $Head
@onready var camera = $Head/Camera3D

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event: InputEvent) → void:
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60))

func _physics_process(delta: float) → void:

if not is_on_floor():
	velocity += get_gravity() * delta

if Input.is_action_just_pressed("space") and is_on_floor():
	velocity.y = JUMP_VELOCITY

if Input.is_action_pressed("sprint"):
	speed = SPRINT_SPEED
else:
	speed = WALK_SPEED

var input_dir = Input.get_vector("right", "left", "up", "down")
var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

if is_on_floor():
	if direction:
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
	else:
		velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0)
		velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0)
else:
	velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
	velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
	
move_and_slide()

`

Question

I tried to get player from stopping mid air if he stops pressing movement key with lerp but it doesn't work

You get better results posting code like this:

```gdscript
code
```

Your code (probably; indenting may be screwed up…) looks like:

extends CharacterBody3D

var speed
const WALK_SPEED = 4.0
const SPRINT_SPEED = 7.0
const JUMP_VELOCITY = 4.5
const SENSITIVITY = 0.003

@onready var head = $Head
@onready var camera = $Head/Camera3D

func _ready():
    Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event: InputEvent) → void:
    if event is InputEventMouseMotion:
        head.rotate_y(-event.relative.x * SENSITIVITY)
        camera.rotate_x(-event.relative.y * SENSITIVITY)
        camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60))

func _physics_process(delta: float) → void:
    if not is_on_floor():
        velocity += get_gravity() * delta

    if Input.is_action_just_pressed("space") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    if Input.is_action_pressed("sprint"):
        speed = SPRINT_SPEED
    else:
        speed = WALK_SPEED

    var input_dir = Input.get_vector("right", "left", "up", "down")
    var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

    if is_on_floor():
        if direction:
            velocity.x = direction.x * speed
            velocity.z = direction.z * speed
        else:
            velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0)
            velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0)
    else:
        velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
        velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
	
     move_and_slide()

The lerp() calls look wrong to me; calling lerp() with delta * 3.0 or whatever for the time value probably isn’t going to produce the results you want. It certainly won’t be linear.

Why is jump setting velocity.y when everything else is operating on x and z?