Files
mercury/ship_camera.gd

46 lines
1.5 KiB
GDScript

extends Node3D
class_name ShipCamera
## Third-person camera for a freely flying ship.
## Stays behind and above the ship regardless of pitch/yaw.
## Attach as a sibling of the ship (child of the scene root), NOT as a child
## of the ship, so it can lag smoothly.
@export var target: ShipController
@export var follow_distance: float = 12.0
@export var follow_height: float = 3.0 ## offset along the ship's local UP
@export var look_ahead: float = 4.0
@export var position_smoothing: float = 5.0
@export var rotation_smoothing: float = 6.0
@onready var camera: Camera3D = $Camera3D
func _ready() -> void:
if not camera:
camera = Camera3D.new()
add_child(camera)
camera.current = true
func _physics_process(delta: float) -> void:
if not target:
return
# "Behind" the ship in its local space (accounts for pitch + yaw)
var ship_back := target.global_transform.basis.z # +Z is behind in Godot
var ship_up := target.global_transform.basis.y
var desired_pos := (
target.global_position
+ ship_back * follow_distance
+ ship_up * follow_height
)
global_position = global_position.lerp(desired_pos, position_smoothing * delta)
# Look at a point ahead of the ship
var ship_forward := -target.global_transform.basis.z
var look_target := target.global_position + ship_forward * look_ahead
var desired_transform := global_transform.looking_at(look_target, Vector3.UP)
global_transform = global_transform.interpolate_with(desired_transform, rotation_smoothing * delta)