|
|
|
@@ -56,6 +56,10 @@ func _setup_viewmodel_viewport() -> void:
|
|
|
|
|
add_child(dir_light)
|
|
|
|
|
|
|
|
|
|
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_yaw: float = 0.0
|
|
|
|
|
var _target_drift_offset: Vector3 = Vector3.ZERO
|
|
|
|
@@ -80,15 +84,32 @@ 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
|
|
|
|
|
target_fov = lerpf(72.0, 80.0, over_speed_factor)
|
|
|
|
|
|
|
|
|
|
# Weapon Viewmodel Bobbing and Drift
|
|
|
|
|
if player.is_on_floor() and hspeed > 1.0:
|
|
|
|
|
# Scale bobbing frequency by walk speed (assuming base walk speed is ~10-11)
|
|
|
|
|
_bob_timer += _delta * 12.0 * (hspeed / 11.0)
|
|
|
|
|
var bob_y = sin(_bob_timer) * 0.015
|
|
|
|
|
var bob_x = cos(_bob_timer * 0.5) * 0.01
|
|
|
|
|
vm_camera.translate_object_local(Vector3(bob_x, bob_y, 0))
|
|
|
|
|
else:
|
|
|
|
|
# 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:
|
|
|
|
|
# Scale bobbing frequency by walk speed
|
|
|
|
|
_bob_timer += _delta * 12.0 * (hspeed / 11.0)
|
|
|
|
|
var bob_y = sin(_bob_timer) * 0.015
|
|
|
|
|
var bob_x = cos(_bob_timer * 0.5) * 0.01
|
|
|
|
|
vm_camera.translate_object_local(Vector3(bob_x, bob_y, 0))
|
|
|
|
|
else:
|
|
|
|
|
_bob_timer = 0.0
|
|
|
|
|
|
|
|
|
|
if not player.is_on_floor():
|
|
|
|
|
# Airborne Drift
|
|
|
|
@@ -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.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
|
|
|
|
|
_recoil_pitch = lerpf(_recoil_pitch, 0.0, 15.0 * _delta)
|
|
|
|
|
_recoil_yaw = lerpf(_recoil_yaw, 0.0, 15.0 * _delta)
|
|
|
|
|