Feat/12 add effects and better animations to fpv #17

Merged
Dotts merged 14 commits from feat/12-add-effects-and-better-animations-to-fpv into main 2026-06-11 19:35:34 -07:00
3 changed files with 51 additions and 12 deletions
Showing only changes of commit 3c512870f2 - Show all commits
+6
View File
@@ -140,6 +140,12 @@ func update(delta: float) -> void:
# Fallback to wall run # Fallback to wall run
var wall_n := machine.detect_wall_horizontal() var wall_n := machine.detect_wall_horizontal()
if wall_n != Vector3.ZERO: if wall_n != Vector3.ZERO:
var w_look_dir := -player.global_transform.basis.z
var h_look := Vector3(w_look_dir.x, 0.0, w_look_dir.z).normalized()
# Require looking mostly along the wall (angle > 41 degrees from normal)
# and inputting mostly along the wall (angle > 31 degrees from normal, allows W+A/D diagonally into wall)
if absf(h_look.dot(wall_n)) < 0.75 and absf(wish_dir.dot(wall_n)) < 0.85:
machine.switch_to("wall_run") machine.switch_to("wall_run")
return return
+6
View File
@@ -204,6 +204,12 @@ func update(delta: float) -> void:
var wall_n := machine.detect_wall_horizontal() var wall_n := machine.detect_wall_horizontal()
if wall_n != Vector3.ZERO: if wall_n != Vector3.ZERO:
if not player.is_on_floor(): if not player.is_on_floor():
var w_look_dir := -player.global_transform.basis.z
var h_look := Vector3(w_look_dir.x, 0.0, w_look_dir.z).normalized()
# Require looking mostly along the wall (angle > 41 degrees from normal)
# and inputting mostly along the wall (angle > 31 degrees from normal, allows W+A/D diagonally into wall)
if absf(h_look.dot(wall_n)) < 0.75 and absf(wish_dir.dot(wall_n)) < 0.85:
machine.switch_to("wall_run") machine.switch_to("wall_run")
return return
+29 -2
View File
@@ -56,6 +56,10 @@ func _setup_viewmodel_viewport() -> void:
add_child(dir_light) add_child(dir_light)
var _bob_timer: float = 0.0 var _bob_timer: float = 0.0
var _current_slide_tilt_z: float = 0.0
var _current_slide_tilt_x: float = 0.0
var _current_slide_offset_x: float = 0.0
var _current_slide_offset_y: float = 0.0
var _recoil_pitch: float = 0.0 var _recoil_pitch: float = 0.0
var _recoil_yaw: float = 0.0 var _recoil_yaw: float = 0.0
var _target_drift_offset: Vector3 = Vector3.ZERO var _target_drift_offset: Vector3 = Vector3.ZERO
@@ -80,9 +84,26 @@ func _process(_delta: float) -> void:
var over_speed_factor = clampf((hspeed - 11.0) / 19.0, 0.0, 1.0) # maxes out at 30 m/s var over_speed_factor = clampf((hspeed - 11.0) / 19.0, 0.0, 1.0) # maxes out at 30 m/s
target_fov = lerpf(72.0, 80.0, over_speed_factor) target_fov = lerpf(72.0, 80.0, over_speed_factor)
# Weapon Viewmodel Bobbing and Drift # Weapon Viewmodel Bobbing, Drift, and Slide Tilt
var is_sliding = player.has_method("get_node") and player.get_node_or_null("MovementStateMachine") and player.get_node("MovementStateMachine").current_state == "slide"
if is_sliding:
_bob_timer = 0.0
# Target tilt when sliding (inwards towards center, pitched slightly down)
# Assuming weapon is on right side (standard FPS), tilting left (positive Z rotation)
_current_slide_tilt_z = lerpf(_current_slide_tilt_z, deg_to_rad(15.0), 12.0 * _delta)
_current_slide_tilt_x = lerpf(_current_slide_tilt_x, 0.0, 12.0 * _delta)
# Move closer to center (negative X) and slightly down (negative Y)
_current_slide_offset_x = lerpf(_current_slide_offset_x, -0.15, 12.0 * _delta)
_current_slide_offset_y = lerpf(_current_slide_offset_y, -0.1, 12.0 * _delta)
else:
_current_slide_tilt_z = lerpf(_current_slide_tilt_z, 0.0, 10.0 * _delta)
_current_slide_tilt_x = lerpf(_current_slide_tilt_x, 0.0, 10.0 * _delta)
_current_slide_offset_x = lerpf(_current_slide_offset_x, 0.0, 10.0 * _delta)
_current_slide_offset_y = lerpf(_current_slide_offset_y, 0.0, 10.0 * _delta)
if player.is_on_floor() and hspeed > 1.0: if player.is_on_floor() and hspeed > 1.0:
# Scale bobbing frequency by walk speed (assuming base walk speed is ~10-11) # Scale bobbing frequency by walk speed
_bob_timer += _delta * 12.0 * (hspeed / 11.0) _bob_timer += _delta * 12.0 * (hspeed / 11.0)
var bob_y = sin(_bob_timer) * 0.015 var bob_y = sin(_bob_timer) * 0.015
var bob_x = cos(_bob_timer * 0.5) * 0.01 var bob_x = cos(_bob_timer * 0.5) * 0.01
@@ -108,6 +129,12 @@ func _process(_delta: float) -> void:
vm_camera.rotate_object_local(Vector3.UP, deg_to_rad(-_current_drift_offset.x * 30.0)) vm_camera.rotate_object_local(Vector3.UP, deg_to_rad(-_current_drift_offset.x * 30.0))
vm_camera.rotate_object_local(Vector3.RIGHT, deg_to_rad(_current_drift_offset.y * 30.0)) vm_camera.rotate_object_local(Vector3.RIGHT, deg_to_rad(_current_drift_offset.y * 30.0))
# Apply slide tilt and offset
if absf(_current_slide_tilt_z) > 0.001 or absf(_current_slide_offset_x) > 0.001:
vm_camera.translate_object_local(Vector3(_current_slide_offset_x, _current_slide_offset_y, 0))
vm_camera.rotate_object_local(Vector3.FORWARD, _current_slide_tilt_z)
vm_camera.rotate_object_local(Vector3.RIGHT, _current_slide_tilt_x)
# Visual Recoil # Visual Recoil
_recoil_pitch = lerpf(_recoil_pitch, 0.0, 15.0 * _delta) _recoil_pitch = lerpf(_recoil_pitch, 0.0, 15.0 * _delta)
_recoil_yaw = lerpf(_recoil_yaw, 0.0, 15.0 * _delta) _recoil_yaw = lerpf(_recoil_yaw, 0.0, 15.0 * _delta)