2023-11-27 13:52:46 +11:00
|
|
|
extends Node3D
|
|
|
|
class_name ViewMovement
|
|
|
|
|
|
|
|
@export var player : Hero
|
|
|
|
@export_category("Bobbing")
|
|
|
|
@export var head_bob_camera : Camera3D
|
|
|
|
@export var head_bob_focus_raycast : RayCast3D
|
|
|
|
@export var enable_head_bob := true
|
2023-12-09 17:22:11 +11:00
|
|
|
@export var head_bob_max_effect_velocity := 6.5
|
|
|
|
@export var head_bob_amplitude := 0.06
|
|
|
|
@export var head_bob_frequency := 0.02
|
2023-11-27 13:52:46 +11:00
|
|
|
@export var target_stabilisation := false
|
|
|
|
@export_category("Tilting")
|
|
|
|
@export var enable_tilt := true
|
2023-12-09 17:22:11 +11:00
|
|
|
@export var tilt_max_effect_velocity := 6.5
|
|
|
|
@export var tilt_amount_x := 0.03
|
|
|
|
@export var tilt_amount_y := 0.00
|
|
|
|
|
|
|
|
var lemniscate_sample_point = 0.0
|
2023-11-27 13:52:46 +11:00
|
|
|
|
|
|
|
|
|
|
|
func _process(delta: float) -> void:
|
2023-12-09 17:22:11 +11:00
|
|
|
var player_velocity = player.velocity.length()
|
2023-11-27 13:52:46 +11:00
|
|
|
if enable_head_bob:
|
2023-12-09 17:22:11 +11:00
|
|
|
check_motion(delta, player_velocity)
|
2023-11-27 13:52:46 +11:00
|
|
|
if target_stabilisation:
|
|
|
|
head_bob_camera.look_at(focus_target())
|
|
|
|
if enable_tilt:
|
2023-12-09 17:22:11 +11:00
|
|
|
tilt_cam(delta, player_velocity)
|
2023-11-27 13:52:46 +11:00
|
|
|
|
|
|
|
|
2023-12-09 17:22:11 +11:00
|
|
|
func check_motion(delta, vel) -> void:
|
|
|
|
var amp = vel / head_bob_max_effect_velocity
|
2023-11-27 13:52:46 +11:00
|
|
|
if !player.is_on_floor():
|
|
|
|
reset_position(delta)
|
|
|
|
return
|
2023-12-09 17:22:11 +11:00
|
|
|
lemniscate_sample_point += (delta * 1000.0) * head_bob_frequency * amp
|
|
|
|
play_motion(sample_lemniscate(lemniscate_sample_point, vel), delta)
|
2023-11-27 13:52:46 +11:00
|
|
|
|
|
|
|
|
|
|
|
func reset_position(delta) -> void:
|
2023-12-08 03:05:11 +11:00
|
|
|
if head_bob_camera.position != Vector3.ZERO:
|
|
|
|
head_bob_camera.position = lerp(head_bob_camera.position, Vector3.ZERO, 7.0 * delta)
|
2023-11-27 13:52:46 +11:00
|
|
|
|
|
|
|
|
2023-12-09 17:22:11 +11:00
|
|
|
func sample_lemniscate(t: float, v: float) -> Vector2:
|
2023-12-08 03:05:11 +11:00
|
|
|
var pos := Vector2.ZERO
|
2023-12-09 17:22:11 +11:00
|
|
|
var amp = head_bob_amplitude * (v / head_bob_max_effect_velocity)
|
|
|
|
pos.y += sin(t) * amp
|
|
|
|
pos.x += cos(t / 2.0) * amp * 2.0
|
2023-11-27 13:52:46 +11:00
|
|
|
return pos
|
|
|
|
|
|
|
|
|
2023-12-08 03:05:11 +11:00
|
|
|
func play_motion(motion: Vector2, delta) -> void:
|
|
|
|
var motion3d = Vector3(motion.x, motion.y, 0.0)
|
|
|
|
head_bob_camera.position = lerp(head_bob_camera.position, motion3d, 7.0 * delta)
|
2023-11-27 13:52:46 +11:00
|
|
|
|
|
|
|
|
|
|
|
func focus_target() -> Vector3:
|
|
|
|
if head_bob_focus_raycast.is_colliding():
|
|
|
|
return head_bob_focus_raycast.get_collision_point()
|
|
|
|
else:
|
|
|
|
return head_bob_focus_raycast.global_position + -head_bob_focus_raycast.global_transform.basis.z * 15.0
|
|
|
|
|
|
|
|
|
2023-12-09 17:22:11 +11:00
|
|
|
func tilt_cam(delta, vel):
|
2023-11-27 13:52:46 +11:00
|
|
|
var dot = player.velocity.normalized().dot(-global_transform.basis.z)
|
|
|
|
dot = -abs(dot) + 1
|
2023-12-09 17:22:11 +11:00
|
|
|
dot *= vel / tilt_max_effect_velocity
|
2023-11-27 13:52:46 +11:00
|
|
|
var input_vector = Input.get_vector("Move Left", "Move Right", "Move Forward", "Move Backward")
|
2023-12-09 17:22:11 +11:00
|
|
|
head_bob_camera.rotation.z = lerp(head_bob_camera.rotation.z, tilt_amount_x * dot * -input_vector.x, 8.0 * delta)
|
|
|
|
head_bob_camera.rotation.x = lerp(head_bob_camera.rotation.x, tilt_amount_y * (1.0 - dot) * input_vector.y, 8.0 * delta)
|