class_name Camera extends Camera3D @export var mouse_sensitivity := Vector2(0.2, 0.2) # degrees per pixel @export var joystick_sensitivity := Vector2(200, 200) # degrees per second @export var pitch_min := -80.0 @export var pitch_max := 80.0 var current_pitch := 0.0 var current_yaw := 0.0 func _unhandled_input(event: InputEvent) -> void: # When pressing escape and mouse is currently captured, release it. if event.is_action_pressed("ui_cancel") && is_mouse_captured(): Input.mouse_mode = Input.MOUSE_MODE_VISIBLE var button := event as InputEventMouseButton if button: # Grab the mouse when pressing the primary mouse button. # TODO: Make "primary mouse button" configurable. if event.button_index == MOUSE_BUTTON_LEFT: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED var mouseMotion := event as InputEventMouseMotion if mouseMotion && is_mouse_captured(): apply_rotation(-mouseMotion.relative * mouse_sensitivity) func _process(delta: float) -> void: # Handle joystick camera controls. var input := Input.get_vector("look_left", "look_right", "look_up", "look_down") apply_rotation(-input * joystick_sensitivity * delta) # Returns whether the mouse is currently captured by the game. func is_mouse_captured() -> bool: return Input.mouse_mode == Input.MOUSE_MODE_CAPTURED # Applies the specified rotation (in degrees) to the camera. func apply_rotation(delta: Vector2) -> void: delta = delta / 360 * TAU current_pitch = clampf(current_pitch + delta.y, deg_to_rad(pitch_min), deg_to_rad(pitch_max)) current_yaw += delta.x