jump ani fixing and transition animations

This commit is contained in:
Nicholas Butzke
2026-08-10 12:50:00 -04:00
parent 833e936bcd
commit 0ce626ad42
13 changed files with 359 additions and 35 deletions
+24 -3
View File
@@ -83,6 +83,9 @@ var grapple_rope: MeshInstance3D
# broadcasts position/velocity; remote peers interpolate toward it (see
# _process). The server stays authoritative for health, shield, and kills.
var synced_movement_state: String = "idle"
## Presentation-only state. Physics/network gameplay still uses
## synced_movement_state; this adds stop and alternating-air variants.
var synced_animation_state: String = "idle"
var synced_movement_speed: float = 0.0
var synced_is_crouching: bool = false
var synced_position: Vector3 = Vector3.ZERO
@@ -91,6 +94,7 @@ var synced_is_ads: bool = false
var synced_wall_side: float = 0.0 # -1 wall left, +1 wall right (wall-glide bank)
var synced_wall_normal: Vector3 = Vector3.ZERO
var synced_wall_contact_point: Vector3 = Vector3.ZERO
var _airborne_alternate := false
var synced_helmet_closed: bool = false
var synced_is_dancing: bool = false # dance emote (B), shown on the model
## Which of the five routines in DanceRoutines is playing. Replicated, so other
@@ -1063,9 +1067,10 @@ func _physics_process(_delta: float) -> void:
synced_is_ads = _read_ads()
# Drive the visual model (skinned GLB or procedural) from local state
var h_speed = Vector2(velocity.x, velocity.z).length()
var animation_state := _visual_animation_state(sm.current_state, h_speed)
var visual = get_visual_model()
if visual:
var h_speed = Vector2(velocity.x, velocity.z).length()
if visual.has_method("set_locomotion"):
var d := _local_move_dir()
visual.set_locomotion(d.x, d.y, 1.0 if synced_is_ads else 0.0)
@@ -1081,7 +1086,7 @@ func _physics_process(_delta: float) -> void:
visual.set_wall_run_motion(velocity)
if visual.has_method("set_helmet_closed"):
visual.set_helmet_closed(synced_helmet_closed)
visual.update_state(sm.current_state, h_speed, sm.input_crouch)
visual.update_state(animation_state, h_speed, sm.input_crouch)
if visual.has_method("set_dancing"):
visual.set_dancing(synced_is_dancing, synced_dance_index)
if visual.has_method("set_grapple_target") and sm.current_state == "grapple":
@@ -1090,6 +1095,7 @@ func _physics_process(_delta: float) -> void:
# Publish state for remote peers
synced_movement_state = sm.current_state
synced_animation_state = animation_state
synced_movement_speed = Vector2(velocity.x, velocity.z).length()
synced_is_crouching = sm.input_crouch
synced_wall_side = sm.wall_side
@@ -1109,6 +1115,17 @@ func _local_move_dir() -> Vector2:
return Vector2(local_vel.x / hspeed, -local_vel.z / hspeed)
func _visual_animation_state(state: String, horizontal_speed: float) -> String:
if state == "air":
return "air_alt" if _airborne_alternate else "air"
if state == "ground" and is_instance_valid(_machine) \
and not _machine.input_crouch \
and _machine.input_dir.length_squared() < 0.01 \
and horizontal_speed > 0.6:
return "stop"
return state
## Whether the local player's active weapon is aiming down sights.
func _read_ads() -> bool:
if not is_instance_valid(camera):
@@ -1130,6 +1147,10 @@ func _on_movement_event(ev: String, data: Dictionary) -> void:
grapple_latch_player.play()
elif ev == "dash":
_speedline_burst = 1.0
elif ev == "jump":
# Alternate the complete authored airborne silhouette on successive
# ground jumps so bunny hops do not always lead with the same knee.
_airborne_alternate = not _airborne_alternate
elif ev == "double_jump":
_trigger_action("double_jump")
if is_instance_valid(_jet_vfx):
@@ -1183,7 +1204,7 @@ func _process(delta: float) -> void:
if visual.has_method("set_helmet_closed"):
visual.set_helmet_closed(synced_helmet_closed)
visual.update_state(
synced_movement_state,
synced_animation_state,
synced_movement_speed,
synced_is_crouching,
)