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 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 wall_cooldown_timer: float = 0.0 # Prevents instant re-attachment after wall jump
|
||||||
var is_crouched: bool = false
|
var is_crouched: bool = false
|
||||||
|
var can_wall_climb: bool = true
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ func update(delta: float) -> void:
|
|||||||
var looking_towards := look_dir.dot(-fwd_wall.normal) > 0.0
|
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))
|
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.wall_normal = fwd_wall.normal
|
||||||
machine.switch_to("wall_climb")
|
machine.switch_to("wall_climb")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ var _footstep_timer: float = 0.0
|
|||||||
func enter(_data: Dictionary = {}) -> void:
|
func enter(_data: Dictionary = {}) -> void:
|
||||||
machine.on_ground = true
|
machine.on_ground = true
|
||||||
machine.current_jump_count = 0
|
machine.current_jump_count = 0
|
||||||
|
machine.can_wall_climb = true
|
||||||
# Clear wall tilt on landing
|
# Clear wall tilt on landing
|
||||||
var rig = _get_camera_rig()
|
var rig = _get_camera_rig()
|
||||||
if rig:
|
if rig:
|
||||||
@@ -96,13 +97,13 @@ func update(delta: float) -> void:
|
|||||||
for i in range(player.get_slide_collision_count()):
|
for i in range(player.get_slide_collision_count()):
|
||||||
var col = player.get_slide_collision(i)
|
var col = player.get_slide_collision(i)
|
||||||
if absf(col.get_normal().y) < 0.3: # Hit a wall
|
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 space_state = player.get_world_3d().direct_space_state
|
||||||
var feet_y = player.global_position.y - (machine.original_capsule_height / 2.0)
|
var feet_y = player.global_position.y - (machine.original_capsule_height / 2.0)
|
||||||
|
|
||||||
# Raycast down from above the step
|
# Raycast down from above the step
|
||||||
var fwd = wish_dir.normalized()
|
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
|
ray_start.y = feet_y + max_step_height + 0.1
|
||||||
var ray_end = ray_start - Vector3.UP * (max_step_height + 0.2)
|
var ray_end = ray_start - Vector3.UP * (max_step_height + 0.2)
|
||||||
|
|
||||||
@@ -121,16 +122,20 @@ func update(delta: float) -> void:
|
|||||||
head_ray.exclude = [player.get_rid()]
|
head_ray.exclude = [player.get_rid()]
|
||||||
|
|
||||||
if space_state.intersect_ray(head_ray).is_empty():
|
if space_state.intersect_ray(head_ray).is_empty():
|
||||||
# We can safely step up
|
# Check if there is enough space to move forward after stepping up
|
||||||
player.global_position.y += step_height + 0.01
|
var test_transform = player.global_transform
|
||||||
if player.head_pivot and player.head_pivot.has_method("add_step_offset"):
|
test_transform.origin.y += step_height + 0.05
|
||||||
player.head_pivot.add_step_offset(-(step_height + 0.01))
|
if not player.test_move(test_transform, fwd * 0.15):
|
||||||
# Push slightly forward to get onto the step
|
# We can safely step up
|
||||||
player.global_position += fwd * 0.1
|
player.global_position.y += step_height + 0.01
|
||||||
# Restore horizontal velocity that was lost from hitting the wall
|
if player.head_pivot and player.head_pivot.has_method("add_step_offset"):
|
||||||
player.velocity.x = hvel.x
|
player.head_pivot.add_step_offset(-(step_height + 0.01))
|
||||||
player.velocity.z = hvel.z
|
# Push slightly forward to get onto the step
|
||||||
break
|
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()
|
_update_capsule_height()
|
||||||
|
|
||||||
@@ -190,7 +195,7 @@ func update(delta: float) -> void:
|
|||||||
var looking_towards := look_dir.dot(-fwd_wall.normal) > 0.0
|
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))
|
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.wall_normal = fwd_wall.normal
|
||||||
machine.switch_to("wall_climb")
|
machine.switch_to("wall_climb")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ func _detach() -> void:
|
|||||||
machine.wall_normal = Vector3.ZERO
|
machine.wall_normal = Vector3.ZERO
|
||||||
machine.wall_side = 0.0
|
machine.wall_side = 0.0
|
||||||
machine.wall_cooldown_timer = 0.3
|
machine.wall_cooldown_timer = 0.3
|
||||||
|
machine.can_wall_climb = false
|
||||||
machine.switch_to("air")
|
machine.switch_to("air")
|
||||||
|
|
||||||
func _vault() -> void:
|
func _vault() -> void:
|
||||||
|
|||||||
Reference in New Issue
Block a user