feat: implement movement state machine architecture and add various sound assets

This commit is contained in:
DottsGit
2026-06-07 16:13:01 -04:00
parent 064bc90f53
commit 22ea918e6d
30 changed files with 372 additions and 13 deletions
+83 -6
View File
@@ -90,6 +90,45 @@ func update(delta: float) -> void:
player.velocity = vel
player.move_and_slide()
# ── Stair Stepping ────────────────────────────────────────────────────
if wish_dir.length_squared() > 0.01 and not machine.input_crouch:
for i in range(player.get_slide_collision_count()):
var col = player.get_slide_collision(i)
if absf(col.get_normal().y) < 0.3: # Hit a wall
var max_step_height = 0.5
var space_state = player.get_world_3d().direct_space_state
var feet_y = player.global_position.y - (machine.original_capsule_height / 2.0)
# Raycast down from above the step
var fwd = wish_dir.normalized()
var ray_start = player.global_position + fwd * 0.5
ray_start.y = feet_y + max_step_height + 0.1
var ray_end = ray_start - Vector3.UP * (max_step_height + 0.2)
var ray = PhysicsRayQueryParameters3D.create(ray_start, ray_end)
ray.exclude = [player.get_rid()]
var hit = space_state.intersect_ray(ray)
if not hit.is_empty() and hit.normal.y > 0.7:
var step_height = hit.position.y - feet_y
if step_height > 0.01 and step_height <= max_step_height:
# Check if we have headroom to move up
var head_ray_start = player.global_position
head_ray_start.y += (machine.original_capsule_height / 2.0)
var head_ray_end = head_ray_start + Vector3.UP * (step_height + 0.1)
var head_ray = PhysicsRayQueryParameters3D.create(head_ray_start, head_ray_end)
head_ray.exclude = [player.get_rid()]
if space_state.intersect_ray(head_ray).is_empty():
# We can safely step up
player.global_position.y += step_height + 0.01
# Push slightly forward to get onto the step
player.global_position += fwd * 0.1
# Restore horizontal velocity that was lost from hitting the wall
player.velocity.x = hvel.x
player.velocity.z = hvel.z
break
_update_capsule_height()
@@ -116,12 +155,50 @@ func update(delta: float) -> void:
machine.switch_to("air")
return
# ── Wall run check ────────────────────────────────────────────────────
var wall_n := machine.detect_wall_horizontal()
if wall_n != Vector3.ZERO and machine.input_dir.length() > 0.1:
if not player.is_on_floor():
machine.switch_to("wall_run")
return
# ── Wall interaction (Run, Climb, Vault) ──────────────────────────────
if machine.input_dir.length() > 0.1 and machine.wall_cooldown_timer <= 0.0 and not machine.input_crouch:
var fwd_wall = machine.detect_wall_forward()
if fwd_wall.hit:
if fwd_wall.is_short:
# Instant Vault
var look_dir := -player.global_transform.basis.z
var h_look := Vector3(look_dir.x, 0.0, look_dir.z)
if h_look.length_squared() > 0.01:
h_look = h_look.normalized()
player.velocity = h_look * params.wall_climb_vault_forward
player.velocity.y = params.wall_climb_vault_up
if player.vault_player:
player.vault_player.play()
# Quick camera animation (tilt up and forward bob)
var camera = player.camera
if camera:
var tween = player.create_tween()
tween.tween_property(camera, "rotation_degrees:x", camera.rotation_degrees.x + 10.0, 0.15).set_trans(Tween.TRANS_SINE)
tween.parallel().tween_property(camera, "v_offset", -0.2, 0.15).set_trans(Tween.TRANS_SINE)
tween.chain().tween_property(camera, "rotation_degrees:x", camera.rotation_degrees.x, 0.2).set_trans(Tween.TRANS_SINE)
tween.parallel().tween_property(camera, "v_offset", 0.0, 0.2).set_trans(Tween.TRANS_SINE)
machine.wall_cooldown_timer = 0.3
machine.switch_to("air")
return
else:
# Check if moving directly into wall and looking generally towards it
var look_dir := -player.global_transform.basis.z
var looking_towards := look_dir.dot(-fwd_wall.normal) > 0.0
var moving_towards := wish_dir.dot(-fwd_wall.normal) > cos(deg_to_rad(params.wall_climb_max_angle))
if looking_towards and moving_towards:
machine.wall_normal = fwd_wall.normal
machine.switch_to("wall_climb")
return
# Fallback to wall run
var wall_n := machine.detect_wall_horizontal()
if wall_n != Vector3.ZERO:
if not player.is_on_floor():
machine.switch_to("wall_run")
return
# ── Dash ──────────────────────────────────────────────────────────────
if machine.input_dash: