Stuck on trying to make acceleration and drag/deceleration system for CharacterBody3D

Godot Version

V4.2.2

Question

So I made a system for simple movement (I’m completely new to Godot and used like 5 different tutorials for this so it’s probably horrible) and I want to add acceleration but I have no idea how to implement it and can’t find any tutorials/forum posts, so any tips how to add it?
Here’s a snippet of my code, I can provide the full code or my unsuccessful attempt to implement acceleration if needed:

run_multi is just a speed multiplier and SPEED is max speed to which I want to be able to accelerate. neck is node which is used for rotating the camera.

const SPEED = 5.0
var run_multi = 1

func _physics_process(delta: float) -> void:
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
	var direction = (neck.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED * run_multi
		velocity.z = direction.z * SPEED * run_multi
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED * run_multi)
		velocity.z = move_toward(velocity.z, 0, SPEED * run_multi)
	
	move_and_slide()

You got a good start, I think you can try changing a bit how you use move_toward. From what I understand it should take delta into account (delta is the time elapsed since last frame).
In your code it will only give you deceleration, if you want to accelerate you need to also use move_toward in the part after if direction:
You can try adding delta like that :

velocity.x = move_toward(velocity.x, 0, SPEED * run_multi * delta)
velocity.z = move_toward(velocity.z, 0, SPEED * run_multi * delta)

This function will likely give you exponential slowdown.

If you want a linear acceleration / deceleration, the easiest way is probably to create a variable current_speed_x (one for x, one for z) that contains how fast you are going compared to your max speed, increase it by delta each frame the user is inputing and decrease it otherwise, also make sure it never goes over 1.0. And then set your velocity to that value (not tested, might not work) :

const MAXSPEED = 5.0
const ACCEL= 1.0
var current_speed_x: float

func _physics_process(delta: float) -> void:
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
	var direction = (neck.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction.x:  # If inputing, we accelerate
		current_speed_x += delta * ACCEL * direction.x
	else:  # else we decelerate
		current_speed_x -= delta * ACCEL
	if direction.z:
		current_speed_z += delta * ACCEL * direction.z, 1.0
	else:
		current_speed_z -= delta * ACCEL
	#You need to add checks to make sure current_speed_x and current_speed_z stay between 0.0 and 1.0
	# Now we update our speeds
	velocity.x = current_speed_x * MAXSPEED
	velocity.z = current_speed_z * MAXSPEED

	move_and_slide()

Thanks, I’ll try!

Used the first suggestion and adjusted it a little, thanks once again :smiley: