big
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user