This commit is contained in:
Nicholas Butzke
2026-08-02 02:20:02 -04:00
parent 61669627db
commit 922983429e
226 changed files with 34032 additions and 18521 deletions
+79 -4
View File
@@ -35,6 +35,14 @@ var calf_r: MeshInstance3D
var current_state: String = "idle"
var movement_speed: float = 0.0
var _anim_time: float = 0.0
var _locomotion_strafe: float = 0.0
var _locomotion_fwd: float = 0.0
var _brake_left: float = 0.0
var _brake_fwd: float = 1.0
var _brake_strength: float = 0.0
var _brake_weight: float = 0.0
var _brake_armed := true
const BRAKE_DURATION := 0.46
func _ready() -> void:
rotation_degrees.y = 180
@@ -240,11 +248,44 @@ func _apply_color(col: Color) -> void:
LevelMaterials.apply_toon_recursive(root_pivot, 0.004)
func update_state(state: String, speed: float, is_crouching: bool = false) -> void:
var previous_speed := movement_speed
var slowdown := previous_speed - speed
if state in ["ground", "idle"]:
if speed > 4.5 and slowdown < 0.05:
_brake_armed = true
if _brake_armed and previous_speed > 4.5 and slowdown > 0.12:
_brake_left = BRAKE_DURATION
_brake_strength = clampf(previous_speed / 10.0, 0.55, 1.0)
_brake_armed = false
if absf(_locomotion_fwd) > 0.15:
_brake_fwd = signf(_locomotion_fwd)
elif state not in ["ground", "idle"]:
_brake_left = 0.0
_brake_armed = true
current_state = state
movement_speed = speed
if is_crouching and current_state == "ground":
current_state = "crouch"
func set_locomotion(strafe: float, fwd: float, _ads: float) -> void:
_locomotion_strafe = clampf(strafe, -1.0, 1.0)
_locomotion_fwd = clampf(fwd, -1.0, 1.0)
func get_jet_socket_world_positions() -> Array[Vector3]:
if not root_pivot:
return []
return [
upper_arm_l_pivot.global_position \
+ root_pivot.global_basis * Vector3(-0.04, -0.02, -0.16),
upper_arm_r_pivot.global_position \
+ root_pivot.global_basis * Vector3(0.04, -0.02, -0.16),
calf_l_pivot.to_global(Vector3(0.0, -0.35, -0.045)),
calf_r_pivot.to_global(Vector3(0.0, -0.35, -0.045)),
]
var is_holding_weapon: bool = false
func set_weapon(script_path: String) -> void:
@@ -336,6 +377,17 @@ func _set_shadows_recursive(node: Node) -> void:
_set_shadows_recursive(child)
func _process(delta: float) -> void:
var brake_target := 0.0
if _brake_left > 0.0 and current_state in ["ground", "idle"]:
_brake_left = maxf(0.0, _brake_left - delta)
var progress := 1.0 - _brake_left / BRAKE_DURATION
var envelope := smoothstep(0.0, 1.0, progress / 0.30) \
if progress < 0.30 else \
1.0 - smoothstep(0.0, 1.0, (progress - 0.30) / 0.70)
brake_target = envelope * _brake_strength
_brake_weight = lerpf(
_brake_weight, brake_target,
1.0 - exp((-22.0 if brake_target > _brake_weight else -10.0) * delta))
var anim_speed = 1.0
if current_state == "ground" and movement_speed > 1.0:
anim_speed = movement_speed * 0.4
@@ -358,7 +410,8 @@ func _process(delta: float) -> void:
"ground", "idle":
if movement_speed > 1.0:
# Run cycle
var swing = sin(_anim_time * 5.0)
var reverse_cycle := -1.0 if _locomotion_fwd < -0.12 else 1.0
var swing = sin(_anim_time * 5.0) * reverse_cycle
# Hips
t_thigh_l_rot.x = -swing * 1.6
t_thigh_r_rot.x = swing * 1.6
@@ -376,6 +429,11 @@ func _process(delta: float) -> void:
# Bounce slightly
t_root_pos.y = abs(cos(_anim_time * 5.0)) * 0.1
# Directional silhouette: reverse travel moves the shoulders
# behind the hips instead of reusing the forward sprint lean.
t_root_rot.x = deg_to_rad(10.0) if _locomotion_fwd < -0.12 \
else deg_to_rad(-8.0)
t_root_rot.z = deg_to_rad(-7.0) * _locomotion_strafe
else:
# Idle
var breath = sin(_anim_time * 2.0)
@@ -465,7 +523,7 @@ func _process(delta: float) -> void:
t_calf_r_rot.x = deg_to_rad(10)
"dash":
t_root_rot.x = deg_to_rad(-70)
t_root_rot.x = deg_to_rad(-38)
t_upper_arm_l_rot.x = deg_to_rad(-170)
t_lower_arm_l_rot.x = 0.0
t_upper_arm_r_rot.x = deg_to_rad(-170)
@@ -487,7 +545,24 @@ func _process(delta: float) -> void:
t_calf_l_rot.x = 0.0
t_thigh_r_rot.x = deg_to_rad(10)
t_calf_r_rot.x = 0.0
# Blend a single catching step over the locomotion result. It rises quickly
# and releases over the same span as the run-to-idle crossfade, preserving
# momentum without freezing the whole mannequin in an exaggerated plant.
if current_state in ["ground", "idle"] and _brake_weight > 0.001:
var travel_sign := -1.0 if _brake_fwd < 0.0 else 1.0
t_root_pos.y = lerpf(t_root_pos.y, -0.025, _brake_weight)
t_root_rot.x = lerp_angle(
t_root_rot.x, deg_to_rad(8.0) * travel_sign, _brake_weight)
t_thigh_r_rot.x = lerp_angle(
t_thigh_r_rot.x, deg_to_rad(-24.0) * travel_sign, _brake_weight)
t_calf_r_rot.x = lerp_angle(
t_calf_r_rot.x, deg_to_rad(12.0) * travel_sign, _brake_weight)
t_thigh_l_rot.x = lerp_angle(
t_thigh_l_rot.x, deg_to_rad(8.0) * travel_sign, _brake_weight)
t_calf_l_rot.x = lerp_angle(
t_calf_l_rot.x, deg_to_rad(14.0), _brake_weight)
# Override right arm (and left) if holding a weapon
if is_holding_weapon and current_state != "death":
# Right arm holds the grip: elbow tucked at the ribs, forearm level so
@@ -503,7 +578,7 @@ func _process(delta: float) -> void:
t_upper_arm_l_rot.z = 0.55
t_lower_arm_l_rot.x = -1.0
var lerp_speed = 40.0 * delta
var lerp_speed := 1.0 - exp(-14.0 * delta)
root_pivot.position = root_pivot.position.lerp(t_root_pos, lerp_speed)
root_pivot.rotation = _lerp_vec3(root_pivot.rotation, t_root_rot, lerp_speed)