62 lines
1.6 KiB
GDScript
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
|