It's a pretty long answer and beyond the level you're meant to be at in the course. I tried to find a relatively accessible solution this morning with raycasts, but it fails in some cases, so I'll come back to you with a more complete video.
It's a topic that could help many people in the community so I think we'll put it on youtube. But I'll need some more time to do this one.
What I tried, that didn't work reliably enough: using a Raycast2D node (you'll learn about this later in the course). With code like this (I tried a bunch of variations). You'll find some comments explaining the logic.
onready var ray_cast_2d: RayCast2D = $CollisionShape2D/RayCast2D
onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
func get_character_unstuck() -> void:
# Make the ray point in the direction the player is moving
if velocity.length() > 0.0:
ray_cast_2d.cast_to = velocity.normalized() * 140.0
# If the character isn't moving, default to the RIGHT direction
ray_cast_2d.cast_to = Vector2.RIGHT * 140.0
# Force the ray to update to get accurate collision information.
# If it's colliding, move the character to the collision point, and offset by the character's collision shape radius in the ray's direction.
var collision_point := ray_cast_2d.get_collision_point()
global_position = collision_point + collision_shape_2d.shape.radius * ray_cast_2d.cast_to.normalized()
It almost always works, but in some cases, like if the ray is pointing down, it will detect a collision with the wall it's inside of, while in other directions, it will usually reliably detect the edges of the walls. I think it's just not designed to be used from inside of a collision shape.
If it worked, it would have been a relatively beginner-friendly solution.
In short, to get a reliable solution to this problem, I would:
1. Manually create physics queries in code. It's like using an Area2D node, but in code, and it lets us instantly check multiple places for collisions, while we don't control when an Area2D's physics information updates.
2. In a loop, we do physics queries with a small circle, we keep looping and offsetting the shape forward in the player's movement direction until the shape doesn't touch any walls. That's a safe place to move the character.
3. We place or animate moving the character at the position of the last query.
I'll work on a code example and a video screencast as soon as possible. I've got a big workload and just spent 1h on a raycast-based solution, so I can't complete it right now. But I'll get back to this!