Hi,
As Godot KinematicBodies are good for snapping to slopes but not for stairs, I extended KinematicBody2D for that purpose.
In short, the idea at a glance is:
- Test collision from current movement before moving on next physics step.
- If the body collides with the floor, collision normal is horizontal and under a y threshold defined in the extended kinematic body, then it is considered that the body collided with a step.
- The body "snaps" to the step, so that it reaches the next one.
func _update_movement_if_stepping_stairs() -> void:
tested_next_collision = move_and_collide(movement, true, true, true)
if tested_next_collision == null:
return
update()
if is_equal_approx(movement.x, 0.0):
return
if abs(tested_next_collision.normal.x) < 0.9:
return
if abs(tested_next_collision.normal.y) > 0.05:
return
var global_position_threshold_step: Vector2 = global_position + Vector2(0.0, threshold_to_snap_on_steps_y)
if !tested_next_collision.position.y > global_position_threshold_step.y:
return
global_position.y -= threshold_to_snap_on_steps_y + get_safe_margin()
As you can see in the attached gif, the next collision is rendered, alongside its normal. Problem is, the normal is not shown as horizontal as expected. Only in frame 152 from gif, when the body is jumping and not touching the floor, the collision normal is shown as horizontal, as expected.
At this point I feel a little lost here, not sure if colliding with the vertical part of the step not bringing an horizontal normal is a bug, if collision with floor (vertical normal) is overriding the one I'm expecting, or if I can follow a different approach to get the result I'm willing.
TIA!
