class_name PlayerController extends CharacterBody3D @export var debug: bool = false @export_category("References") @export var camera: CameraController @export var camera_effects: CameraEffects @export var state_chart: StateChart @export var standing_collision: CollisionShape3D @export var crouching_collision: CollisionShape3D @export var crouch_check: ShapeCast3D @export var interaction_raycast: RayCast3D @export var step_handler: StepHandlerComponet @export_category("Movement Settings") @export_group("Easing") @export var acceleration: float = 0.2 @export var deceleration: float = 0.5 @export_group("Speed") @export var default_speed: float = 7.0 @export var sprint_speed: float = 3.0 @export var crouch_speed: float = -5.0 @export_category("Jump Settings") @export var jump_velocity: float = 5.0 @export var fall_velocity_threashold: float = -5.0 var _input_dir: Vector2 = Vector2.ZERO var _movement_velocity: Vector3 = Vector3.ZERO var sprint_modifier: float = 0.0 var crouch_modifier: float = 0.0 var speed: float = 0.0 var current_fall_velocity: float var previous_velocity: Vector3 func _physics_process(delta: float) -> void: previous_velocity = self.velocity if not is_on_floor(): velocity += get_gravity() * delta var speed_modifier = sprint_modifier + crouch_modifier speed = default_speed + speed_modifier _input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") var current_velocity = Vector2(_movement_velocity.x, _movement_velocity.z) var direction = (transform.basis * Vector3(_input_dir.x, 0, _input_dir.y)).normalized() if direction: current_velocity = lerp(current_velocity, Vector2(direction.x, direction.z) * speed, acceleration) else: current_velocity = current_velocity.move_toward(Vector2.ZERO, deceleration) _movement_velocity = Vector3(current_velocity.x, velocity.y, current_velocity.y) velocity = _movement_velocity move_and_slide() if is_on_floor(): step_handler.handle_step_climbing() func get_input_direction() -> Vector2: return _input_dir func update_rotation(rotation_input) -> void: global_transform.basis = Basis.from_euler(rotation_input) func sprint() -> void: sprint_modifier = sprint_speed func walk() -> void: sprint_modifier = 0.0 func stand() -> void: crouch_modifier = 0.0 standing_collision.disabled = false crouching_collision.disabled = true func crouch() -> void: crouch_modifier = crouch_speed standing_collision.disabled = true crouching_collision.disabled = false func jump() -> void: velocity.y += jump_velocity func check_fall_speed() -> bool: if current_fall_velocity < fall_velocity_threashold: current_fall_velocity = 0.0 return true current_fall_velocity = 0.0 return false