1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
class_name FollowCamera
extends Camera3D
const ROTATE_SPEED: float = 1.5
const ROTATE_WEIGHT: float = 8.0
const ROTATE_UP_SPEED: float = 0.7
const ROTATE_UP_WEIGHT: float = 4.0
const ANGLE_UP_MIN: float = 0.5
const ANGLE_UP_MAX: float = 1.2
const LOOK_WEIGHT: float = 8.0
const MOVE_WEIGHT: float = 2.0
const CAMERA_DISTANCE: float = 10
@export var target: Node3D
var angle_target: float = 0
var angle: float = 0
var angle_up_target: float = 1
var angle_up: float = 1
var ground: Vector3
func _ready():
if target == null:
push_warning("target is not set")
else:
ground = target.position
func _process(delta):
if target != null:
follow(delta)
func follow(delta):
var new_transform = transform.looking_at(target.position)
transform.basis = transform.basis.from_euler(Vector3(
lerp_angle(transform.basis.get_euler().x, new_transform.basis.get_euler().x, delta * LOOK_WEIGHT),
lerp_angle(transform.basis.get_euler().y, new_transform.basis.get_euler().y, delta * LOOK_WEIGHT),
lerp_angle(transform.basis.get_euler().z, new_transform.basis.get_euler().z, delta * LOOK_WEIGHT)
))
angle_target += Input.get_axis("rotate_left", "rotate_right") * ROTATE_SPEED * delta
angle = lerp_angle(angle, angle_target, delta * ROTATE_WEIGHT)
angle_up_target += Input.get_axis("rotate_down", "rotate_up") * ROTATE_UP_SPEED * delta
angle_up_target = clamp(angle_up_target, ANGLE_UP_MIN, ANGLE_UP_MAX)
angle_up = lerp_angle(angle_up, angle_up_target, delta * ROTATE_UP_WEIGHT)
ground = ground.lerp(target.position, delta * MOVE_WEIGHT)
position = ground + Vector3(0, sin(angle_up) * CAMERA_DISTANCE, cos(angle_up) * CAMERA_DISTANCE).rotated(Vector3.UP, angle)
|