class_name ThirdPersonCamera extends Node3D const CROSSHAIR_MOUSE_JOSTLE: float = 0.6 const CORRECTION_SPEED: float = 10 @export var yaw_sensitivity: float = 0.4 @export var yaw_acceleration: float = 20.0 @export var pitch_sensitivity: float = 0.4 @export var pitch_acceleration: float = 20.0 @export_range(-90.0, 90.0) var pitch_min: float = -70.0 @export_range(-90.0, 90.0) var pitch_max: float = 75.0 @export var invert_pitch: bool = false @onready var _target: Vector2 = Vector2(global_rotation_degrees.x, rotation_degrees.y) @onready var _crosshair: Crosshair = get_tree().get_first_node_in_group("CrosshairGroup") func _ready() -> void: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED func jostle(delta: float) -> void: rotation_degrees.z += delta func _unhandled_input(event: InputEvent) -> void: if event is InputEventMouseMotion: var motion: Vector2 = (event as InputEventMouseMotion).relative _target.y = _target.y - motion.x * yaw_sensitivity _target.x = clampf( _target.x + motion.y * pitch_sensitivity * (-1 if invert_pitch else 1), pitch_min, pitch_max ) _crosshair.jostle(motion * CROSSHAIR_MOUSE_JOSTLE) func _physics_process(delta: float) -> void: rotation_degrees.y = lerpf(rotation_degrees.y, _target.y, delta * yaw_acceleration) rotation_degrees.x = lerpf(rotation_degrees.x, _target.x, delta * pitch_acceleration) rotation_degrees.z = lerpf(rotation_degrees.z, 0.0, delta * CORRECTION_SPEED)