class_name MovementController extends Node ## Character movement controller @export var movement_enabled := true @export_group("Speed") @export var run_speed := 80.0 @export var sprint_speed := 160.0 @export var air_speed_factor := 0.1 @export_group("Jump") @export var jump_force := 4.0 @export_group("Friction") @export var ground_friction := 0.3 @export var air_friction := 0.04 var sprinting := false var movement := Vector2.ZERO @onready var character: CharacterBody3D = get_parent() func get_speed() -> float: var speed := run_speed if sprinting: speed = sprint_speed if not character.is_on_floor(): speed *= air_speed_factor return speed func get_friction() -> float: return ground_friction if character.is_on_floor() else air_friction ## Make the character jump. func jump() -> void: if movement_enabled and character.is_on_floor(): character.velocity.y = jump_force func _physics_process(delta: float) -> void: if not character.is_on_floor(): # Apply gravity character.velocity += character.get_gravity() * delta if movement_enabled: # Apply movement input var rel_movement := movement.rotated(-character.global_rotation.y) var direction := Vector3(rel_movement.x, 0, rel_movement.y).normalized() var motion := direction * get_speed() * delta character.velocity.x += motion.x character.velocity.z += motion.z # Apply friction var weight := 1.0 - exp(-get_friction() * 60 * delta) character.velocity.x = lerpf(character.velocity.x, 0, weight) character.velocity.z = lerpf(character.velocity.z, 0, weight) character.move_and_slide()