feat: implement modular movement state machine and ground, air, and wall climb states
This commit is contained in:
@@ -46,6 +46,7 @@ var original_capsule_height: float = 1.8
|
||||
var slide_cooldown_timer: float = 0.0 # Prevents instant slide re-entry
|
||||
var wall_cooldown_timer: float = 0.0 # Prevents instant re-attachment after wall jump
|
||||
var is_crouched: bool = false
|
||||
var can_wall_climb: bool = true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
@@ -132,7 +132,7 @@ func update(delta: float) -> void:
|
||||
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:
|
||||
if looking_towards and moving_towards and machine.can_wall_climb:
|
||||
machine.wall_normal = fwd_wall.normal
|
||||
machine.switch_to("wall_climb")
|
||||
return
|
||||
|
||||
@@ -10,6 +10,7 @@ var _footstep_timer: float = 0.0
|
||||
func enter(_data: Dictionary = {}) -> void:
|
||||
machine.on_ground = true
|
||||
machine.current_jump_count = 0
|
||||
machine.can_wall_climb = true
|
||||
# Clear wall tilt on landing
|
||||
var rig = _get_camera_rig()
|
||||
if rig:
|
||||
@@ -96,13 +97,13 @@ func update(delta: float) -> void:
|
||||
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 max_step_height = 0.95
|
||||
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
|
||||
var ray_start = player.global_position + fwd * 0.65
|
||||
ray_start.y = feet_y + max_step_height + 0.1
|
||||
var ray_end = ray_start - Vector3.UP * (max_step_height + 0.2)
|
||||
|
||||
@@ -121,6 +122,10 @@ func update(delta: float) -> void:
|
||||
head_ray.exclude = [player.get_rid()]
|
||||
|
||||
if space_state.intersect_ray(head_ray).is_empty():
|
||||
# Check if there is enough space to move forward after stepping up
|
||||
var test_transform = player.global_transform
|
||||
test_transform.origin.y += step_height + 0.05
|
||||
if not player.test_move(test_transform, fwd * 0.15):
|
||||
# We can safely step up
|
||||
player.global_position.y += step_height + 0.01
|
||||
if player.head_pivot and player.head_pivot.has_method("add_step_offset"):
|
||||
@@ -190,7 +195,7 @@ func update(delta: float) -> void:
|
||||
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:
|
||||
if looking_towards and moving_towards and machine.can_wall_climb:
|
||||
machine.wall_normal = fwd_wall.normal
|
||||
machine.switch_to("wall_climb")
|
||||
return
|
||||
|
||||
@@ -93,6 +93,7 @@ func _detach() -> void:
|
||||
machine.wall_normal = Vector3.ZERO
|
||||
machine.wall_side = 0.0
|
||||
machine.wall_cooldown_timer = 0.3
|
||||
machine.can_wall_climb = false
|
||||
machine.switch_to("air")
|
||||
|
||||
func _vault() -> void:
|
||||
|
||||
Reference in New Issue
Block a user