generated from krampus/template-godot4
62 lines
1.6 KiB
GDScript
62 lines
1.6 KiB
GDScript
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()
|