Improved camera

This commit is contained in:
2024-02-10 00:10:51 +01:00
parent c3812dd54e
commit da869e0185
10 changed files with 194 additions and 114 deletions

View File

@ -1,46 +1,32 @@
extends Camera3D
@export_group("Main")
@export var follow_node: Node3D
@export var pivot_node: Node3D
@export_group("Zoom")
@export var zoom_speed := 0.5
@export var zoom_interpolation := 10.0
@export var zoom_min := 2.0
@export var zoom_max := 8.0
@export_group("Follow")
@export var follow_enabled: bool
@export var follow_speed: float
@export_group("Shake")
@export var shake_strength := 1.0
@export var shake_decay := 0.8
@export var shake_noise: Noise
var trauma := 0.0
var trauma_time := 0.0
var target_distance: float
func _ready():
target_distance = position.z
Global.camera = self
func _unhandled_input(event):
if event.is_action_pressed("zoom_in"):
target_distance -= zoom_speed
on_distance_changed()
if event.is_action_pressed("zoom_out"):
target_distance += zoom_speed
on_distance_changed()
func on_distance_changed():
target_distance = clampf(target_distance, zoom_min, zoom_max)
Global.camera_attributes.dof_blur_far_distance = target_distance + 1.0
func _process(delta):
if Global.player == null:
if abs(target_distance - position.z) < 0.01:
return
if follow_enabled:
follow_node.position = lerp(follow_node.position, Global.player.position, follow_speed * delta)
else:
follow_node.position = Global.player.position
if trauma:
trauma = max(trauma - shake_decay * delta, 0)
trauma_time += 4096 * delta
_shake(trauma_time)
else:
look_at(pivot_node.global_position)
trauma_time = 0
func _shake(time):
var trauma_sq := trauma * trauma
rotation.x += shake_noise.get_noise_2d(time, 0) * trauma_sq * shake_strength
rotation.y += shake_noise.get_noise_2d(time, 1) * trauma_sq * shake_strength
rotation.z += shake_noise.get_noise_2d(time, 2) * trauma_sq * shake_strength
func add_shake(amount: float):
trauma = min(trauma + amount, 1.0)
position.z = lerpf(position.z, target_distance, zoom_interpolation * delta)

23
client/camera/Camera.tscn Normal file
View File

@ -0,0 +1,23 @@
[gd_scene load_steps=4 format=3 uid="uid://cpdoq0oh84mfw"]
[ext_resource type="Script" path="res://camera/FollowPlayer.gd" id="1_48rtd"]
[ext_resource type="Script" path="res://camera/CameraPivot.gd" id="2_dylfm"]
[ext_resource type="Script" path="res://camera/Camera.gd" id="2_pwdc2"]
[node name="Follow" type="Marker3D"]
script = ExtResource("1_48rtd")
interpolate = true
speed = 10.0
[node name="Pivot" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, 0)
script = ExtResource("2_dylfm")
sensitivity = 0.2
[node name="Camera" type="Camera3D" parent="Pivot"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7.5)
current = true
fov = 45.0
size = 10.0
far = 1000.0
script = ExtResource("2_pwdc2")

View File

@ -0,0 +1,26 @@
extends Node3D
@export var sensitivity: float
var enabled: bool
func _ready():
assert(rotation_order == EULER_ORDER_YXZ)
func _unhandled_input(event):
if event.is_action_pressed("look"):
enabled = true
DisplayServer.mouse_set_mode(DisplayServer.MOUSE_MODE_CAPTURED)
if event.is_action_released("look"):
enabled = false
DisplayServer.mouse_set_mode(DisplayServer.MOUSE_MODE_VISIBLE)
if !enabled:
return
if not event is InputEventMouseMotion:
return
rotation.x += deg_to_rad(-event.relative.y * sensitivity)
rotation.y += deg_to_rad(-event.relative.x * sensitivity)

View File

@ -0,0 +1,26 @@
extends Node3D
@export var shake_strength := 1.0
@export var shake_decay := 0.8
@export var shake_noise: Noise
var trauma := 0.0
var trauma_time := 0.0
func _process(delta):
if trauma:
trauma = max(trauma - shake_decay * delta, 0)
trauma_time += 4096 * delta
_shake(trauma_time)
else:
rotation = Vector3.ZERO
trauma_time = 0
func _shake(time):
var trauma_sq := trauma * trauma
rotation.x += shake_noise.get_noise_2d(time, 0) * trauma_sq * shake_strength
rotation.y += shake_noise.get_noise_2d(time, 1) * trauma_sq * shake_strength
rotation.z += shake_noise.get_noise_2d(time, 2) * trauma_sq * shake_strength
func add_shake(amount: float):
trauma = min(trauma + amount, 1.0)

View File

@ -0,0 +1,14 @@
extends Node3D
@export var interpolate: bool
@export var speed: float
func _process(delta):
if Global.player == null:
return
if interpolate:
position = lerp(position, Global.player.position, speed * delta)
else:
position = Global.player.position