Files
train-game/scripts/camera_rig.gd
2026-08-29 11:44:31 +02:00

62 lines
1.6 KiB
GDScript

extends Node3D
## Aussenkamera: folgt dem Zug, drehbar und zoombar.
const MIN_DIST := 14.0
const MAX_DIST := 140.0
var target: Node3D
var yaw := 0.0
var pitch := deg_to_rad(-34.0)
var distance := 46.0
var _cam: Camera3D
var _focus := Vector3.ZERO
func _ready() -> void:
_cam = Camera3D.new()
_cam.fov = 50.0
_cam.far = 900.0
add_child(_cam)
func activate() -> void:
_cam.current = true
func is_active() -> bool:
return _cam.current
func _unhandled_input(event: InputEvent) -> void:
if not is_active():
return
if event is InputEventMouseButton and event.pressed:
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
distance = clampf(distance * 0.88, MIN_DIST, MAX_DIST)
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
distance = clampf(distance * 1.14, MIN_DIST, MAX_DIST)
func _process(delta: float) -> void:
if not is_active():
if target:
_focus = target.global_position
return
var turn := 0.0
if Input.is_key_pressed(KEY_A) or Input.is_key_pressed(KEY_LEFT):
turn += 1.0
if Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT):
turn -= 1.0
yaw += turn * 1.5 * delta
if Input.is_key_pressed(KEY_R):
pitch = clampf(pitch + 0.9 * delta, deg_to_rad(-82.0), deg_to_rad(-8.0))
if Input.is_key_pressed(KEY_F):
pitch = clampf(pitch - 0.9 * delta, deg_to_rad(-82.0), deg_to_rad(-8.0))
if target:
_focus = _focus.lerp(target.global_position, clampf(delta * 5.0, 0.0, 1.0))
position = _focus
var dir := Vector3(0, 0, 1).rotated(Vector3.RIGHT, pitch).rotated(Vector3.UP, yaw)
_cam.position = dir * distance
_cam.look_at(global_position + Vector3(0, 2.5, 0), Vector3.UP)
func snap_to(p: Vector3) -> void:
_focus = p
position = p