Reducing air control

Godot Version

Godot 4.3 web editor

Question

How would I ake it so the player has less air control can still move in the air but barely

Code

@onready var head: Node3D = $Head
@onready var standing_collision_shape: CollisionShape3D = $StandingCollisionShape
@onready var crouching_collison_shape: CollisionShape3D = $CrouchingCollisonShape
@onready var camera: Camera3D = $Head/Camera3D

var current_speed = 5.0
var direction = Vector3.ZERO
var lerp_speed = 10.0
const walking_speed = 5.0
const springing_speed = 8.0
const crouching_speed = 3.0
const mouse_sense = 0.4

const JUMP_VELOCITY = 4.5
var crouching_depth = -0.5
@onready var ray_cast_3d: RayCast3D = $RayCast3D



func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
	
	if event is InputEventMouseMotion:
		rotate_y(deg_to_rad(-event.relative.x * mouse_sense))
		head.rotate_x(deg_to_rad(-event.relative.y * mouse_sense))
		head.rotation.x = clamp(head.rotation.x,deg_to_rad(-89), deg_to_rad(89))

func _physics_process(delta):
	if Input.is_action_pressed("Crouch"):
		current_speed = crouching_speed
		head.position.y = lerp(head.position.y,1.2 + crouching_depth, delta*lerp_speed)
		standing_collision_shape.disabled = true
		crouching_collison_shape.disabled = false
		camera.fov = lerpf(camera.fov, (75 if Input.is_action_pressed("Null") else 65), delta*10.0)
	elif !ray_cast_3d.is_colliding():
		standing_collision_shape.disabled = false
		crouching_collison_shape.disabled = true
		
		head.position.y = lerp(head.position.y,1.2,delta*lerp_speed)
		
		if Input.is_action_pressed("Sprint"):
			current_speed = springing_speed
		else:
			current_speed = walking_speed
		camera.fov = lerpf(camera.fov, (75 if Input.is_action_pressed("Sprint") else 65), delta*10.0)
		
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("Left", "Right", "Forward", "Backward")
	direction = lerp(direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*lerp_speed)
	if direction:
		velocity.x = direction.x * current_speed
		velocity.z = direction.z * current_speed
	else:
		velocity.x = move_toward(velocity.x, 0, current_speed)
		velocity.z = move_toward(velocity.z, 0, current_speed)

	move_and_slide()

You can achieve this by interpolating the velocity. You are using lerp already on the direction vector which I haven’t seen before, but to each their own. When the player isn’t on the ground, you can add a lerp when you apply speed to velocity like this:

## TOP OF SCRIPT ##
const MAX_SPEED = 300
const MAX_AIR_SPEED = 100.0 # Change this to whatever speed you want
var current_speed : float = 0.0
var grounded: bool = false # False if on ground - true if in air
################

## In physics_process() ##
grounded = is_on_floor()
if direction:
	if !grounded:
		current_speed = lerp(current_speed, MAX_AIR_SPEED, 10.0 * delta) # Change the "0.01" value to give more or less control  
	else:
		current_speed = MAX_SPEED	
	velocity.x = direction * current_speed
	velocity.z = direction * current_speed
else:
	current_speed = 0 # Reset to 0 so the lerp doesn't pickup at the previous value
	velocity.x = move_toward(velocity.x, 0, SPEED)
	velocity.z = move_toward(velocity.z, 0, SPEED)

On a side note. I don’t personally use lerp on the direction vector because it’s used to get the pure, direct input from the player. Meaning you’re getting an altered value from what the player is actually inputting. When using the direction for other parts of your player controller. You’re always working on an unreliable value.

This is why it’s better(in my opinion) to have the clean and clear input values in the direction variable and if you want to lerp a subsequent value as a result from the direction, you can lerp, alter or change that subsequent value instead. This is what is done with the code I provided. Instead of lerping the direction, we lerp the current speed which is affected by the input direction.

Of course, you can do what you want and I’m not saying that you’re doing something incorrect by any means. Just warning you of a potential downside.