+extends Node3D
+class_name CameraHandler
+
+
+enum CameraInput {MOUSE, JOYSTICK}
+
+@export_range(1.0, 10.0) var camera_distance := 3.0
+@export_range(0.0, 1.0) var mouse_sensitivity := 0.15
+@export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0
+@export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5
+@export_range(0.0, 10.0) var joystick_sensitivity_x := 4.0
+@export_range(0.0, 10.0) var joystick_sensitivity_y := 2.0
+
+
+var camera_input_method := CameraInput.MOUSE
+var camera_input_direction := Vector2.ZERO
+var player_input_direction := Vector2.ZERO
+
+
+@onready var _input: InputHandler = %Input
+@onready var _spring: SpringArm3D = $spring
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready() -> void:
+ _spring.spring_length = camera_distance
+
+
+func _unhandled_input(event: InputEvent) -> void:
+ # If user clicks on the window, capture the mouse and direct the camera with it
+ if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
+ return
+
+ #_camera_input_direction *= mouse_sensitivity
+ if event is InputEventMouseMotion:
+ camera_input_method = CameraInput.MOUSE
+ camera_input_direction = event.screen_relative * mouse_sensitivity
+ elif event is InputEventJoypadMotion:
+ # TODO: add these settings!
+ camera_input_method = CameraInput.JOYSTICK
+ camera_input_direction = _input.get_camera_input_direction()
+ camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y)
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta: float) -> void:
+ # vertical camera rotation
+ rotation.x += camera_input_direction.y * mouse_sensitivity_y * delta
+ rotation.x = clamp(rotation.x, -PI / 6, PI / 3)
+
+ # horizontal camera rotation
+ rotation.y -= camera_input_direction.x * mouse_sensitivity_x * delta
+
+ # reset mouse movement vector if mouse input
+ if camera_input_method == CameraInput.MOUSE:
+ camera_input_direction = Vector2.ZERO
+
+ # change spring length
+ _spring.spring_length = lerp(
+ _spring.spring_length, camera_distance, delta
+ )