Raycasting is a common technique in game development. “Casting a ray” means extending a line from a point until it collides with something or reaches its limit.
RayCast2D node and take a look at the Inspector:
Here are the main properties you’ll need to understand:
Turn this on to make the raycast work. This property is disabled by default!
This property causes the ray to ignore collisions with the parent object. Enabled by default.
This is the destination point of the ray. Note: This is in local coordinates.
Also, take note of the Collide With section. By default the ray will only detect bodies, so you’ll need to go here if you want to detect areas as well or instead.
You can see the full list of the node’s functions in the API Documentation. Here are the some of the most useful ones:
Boolean function, lets you know if the ray is colliding with something.
If the ray is colliding, this will return the position of the collision (in global coordinates).
If the ray is colliding, this function will return a reference to the colliding object.
Another useful piece of information, this is the normal of the collided object at the point of collision.
There are many uses for raycasts: visibility (can A see B, or is there an obstacle between?), proximity (am I close to a wall/ground/obstacle?), etc. Here are a couple of practical examples in use:
Fast-moving projectiles often have the problem of “tunneling” through obstacles - they are moving too fast for the collision to be detected in a single frame. As an alternative, you can use a
Raycast2D to represent the path (or a laser, etc.).
Here’s a player sprite with a raycast attached to the end of the gun. The
cast_to is set to
When the player shoots, you check to see if the ray is colliding with something:
func _input(event): if event.is_action_pressed("shoot"): if $RayCast2D.is_colliding(): print($RayCast2D.get_collider().name)
Consider a platformer enemy that walks on platforms, but you don’t want it to fall off the edges. Add two downward-pointing raycasts to the mob like so:
In the mob’s script, check for when the ray stops colliding. That means you’ve found the edge and should turn around:
func _physics_process(delta): velocity.y += gravity * delta if not $RayRight.is_colliding(): dir = -1 if not $RayLeft.is_colliding(): dir = 1 velocity.x = dir * speed $AnimatedSprite.flip_h = velocity.x > 0 velocity = move_and_slide(velocity, Vector2.UP)
Here’s what it looks like in action: