generated from krampus/template-godot4
71 lines
2.3 KiB
GDScript
71 lines
2.3 KiB
GDScript
class_name FreeCamera extends CharacterBody3D
|
|
|
|
const SPRINT_MULT := 3.0
|
|
const PITCH_LIMIT := deg_to_rad(85.0)
|
|
|
|
var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed")
|
|
|
|
var x_sensitivity: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/x_axis_sensitivity"
|
|
)
|
|
var x_acceleration: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/x_axis_acceleration"
|
|
)
|
|
var y_sensitivity: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/y_axis_sensitivity"
|
|
)
|
|
var y_acceleration: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/y_axis_acceleration"
|
|
)
|
|
|
|
var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch")
|
|
|
|
@onready var _target := Vector2(rotation.x, rotation.y)
|
|
|
|
static var scene := preload("res://src/ui/camera/free_camera/free_camera.tscn")
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton:
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
elif event is InputEventMouseMotion:
|
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
|
camera_motion((event as InputEventMouseMotion).relative)
|
|
|
|
|
|
func camera_motion(motion: Vector2) -> void:
|
|
_target.y = _target.y - deg_to_rad(motion.x * x_sensitivity)
|
|
_target.x = clampf(
|
|
_target.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1),
|
|
-PITCH_LIMIT,
|
|
PITCH_LIMIT,
|
|
)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
# Rotation
|
|
rotation.y = lerp_angle(rotation.y, _target.y, delta * x_acceleration)
|
|
rotation.x = lerp_angle(rotation.x, _target.x, delta * y_acceleration)
|
|
|
|
# Handle spatial movement
|
|
var xz_input := Input.get_vector("camera_left", "camera_right", "camera_forward", "camera_back")
|
|
var y_input := Input.get_vector("camera_down", "camera_up", "camera_down", "camera_up")
|
|
var direction := (transform.basis * Vector3(xz_input.x, y_input.y, xz_input.y)).normalized()
|
|
|
|
var speed := base_speed
|
|
if Input.is_action_pressed("camera_sprint"):
|
|
speed *= SPRINT_MULT
|
|
|
|
if direction:
|
|
velocity = direction * speed
|
|
else:
|
|
velocity = velocity.move_toward(Vector3.ZERO, speed)
|
|
|
|
move_and_slide()
|
|
|
|
|
|
static func create(snap_point: Node3D) -> FreeCamera:
|
|
var instance: FreeCamera = FreeCamera.scene.instantiate()
|
|
instance.global_transform = snap_point.global_transform
|
|
return instance
|