generated from krampus/template-godot4
53 lines
1.5 KiB
GDScript
53 lines
1.5 KiB
GDScript
class_name OrbitalCamera extends Node3D
|
|
|
|
const POSITION_ACCELERATION := 4.0
|
|
const BASIS_ACCELERATION := 4.0
|
|
const TARGETER_ACCELERATION := 4.0
|
|
|
|
@export var target: Node3D
|
|
@export var offset := Vector3(0, 1, 0)
|
|
|
|
@export var angular_speed := 0.007
|
|
|
|
var target_basis := Basis.IDENTITY
|
|
|
|
@onready var pivot: Node3D = %Pivot
|
|
@onready var camera: Camera3D = %Camera
|
|
@onready var targeter: Node3D = %Targeter
|
|
|
|
static var scene := preload("res://src/ui/camera/orbital_camera/orbital_camera.tscn")
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
var up := Vector3.UP
|
|
# If target is a game ball, realign to gravity
|
|
if target is GameBall:
|
|
up = -(target as GameBall).current_gravity.normalized()
|
|
var right := up.cross(global_basis.z).normalized()
|
|
var forward := right.cross(up).normalized()
|
|
target_basis = Basis(right, up, forward)
|
|
|
|
# Slerp to basis
|
|
global_basis = global_basis.slerp(target_basis, delta * BASIS_ACCELERATION)
|
|
|
|
# Update position
|
|
global_position = global_position.lerp(
|
|
target.global_position + offset, delta * POSITION_ACCELERATION
|
|
)
|
|
|
|
# Update rotation
|
|
#camera.look_at(target.global_position, up)
|
|
targeter.look_at(target.global_position, up)
|
|
camera.global_basis = camera.global_basis.slerp(
|
|
targeter.global_basis.orthonormalized(), delta * TARGETER_ACCELERATION
|
|
)
|
|
|
|
# Update phase angle
|
|
pivot.rotation.y += angular_speed
|
|
|
|
|
|
static func create(_target: Node3D) -> OrbitalCamera:
|
|
var instance: OrbitalCamera = scene.instantiate()
|
|
instance.target = _target
|
|
return instance
|