Understanding raycasts in Godot

Raycasts are one of the most versatile tools in a game developer's toolbox, and you'll find yourself using them in many situations.

A raycast is an invisible line that detects and reports physics objects it hits. That's it! Despite this simplicity, raycasts are powerful in practice. You can use them to create lines of sight, handle ground detection, implement weapons, and much more.

This animation illustrates a raycast using an arrow that turns red when it detects a collision with the game world.

In this guide, you'll learn:

What is a raycast?

A raycast is an invisible line with a direction and a limited length. It checks for collisions with physics objects along its path and gives you information about the first object it hits.

Think of a raycast like a laser pointer. It travels in a straight line until it hits something, and then it tells you what it hit and exactly where the collision happened.

When a raycast hits something, it reports:

You can use this information to create all sorts of gameplay mechanics - from spawning an impact visual effect where a bullet hits a wall to reflecting a beam of light that lands on a mirror.

Setting up raycast nodes in Godot

Godot has two nodes for raycasting in 2D and 3D games, respectively:

Both nodes work similarly. The most important property of a raycast node is target_position, which defines:

In 2D, this is a Vector2, while in 3D it's a Vector3 value.

The start position of the ray is controlled by the node's position in the scene, and the target_position property is relative to this starting point.

By default, raycasts are enabled and check for collisions on every physics update automatically. You can turn them off by changing the Enabled property and call the force_raycast_update() function to control exactly when the ray updates. This gives you more control over performance and precision.

Also, by default:

Using raycasts in code

Let's look at an example of setting up and using a raycast in 2D where we make the ray point 500 pixels downward:

extends Node2D

@onready var ray_cast_2d: RayCast2D = $RayCast2D

func _ready() -> void:
	ray_cast_2d.target_position = Vector2.DOWN * 500.0

func _physics_process(delta: float) -> void:
	if ray_cast_2d.is_colliding():
		var collision_point: Vector2 = ray_cast_2d.get_collision_point()
		var collision_normal: Vector2 = ray_cast_2d.get_collision_normal()
		var collider: Node2D = ray_cast_2d.get_collider()

There are four important raycast functions in this code:

Now, here's the 3D equivalent. In this example, we point the ray forward (remember that the negative Z-axis is the forward direction in Godot):

extends Node3D

@onready var raycast: RayCast3D = $RayCast3D

func _ready() -> void:
	raycast.target_position = Vector3.FORWARD * 8.0

func _physics_process(delta: float) -> void:
	if raycast.is_colliding():
		var collision_point: Vector3 = raycast.get_collision_point()
		var collision_normal: Vector3 = raycast.get_collision_normal()
		var collider: Node3D = raycast.get_collider()

Common use cases

Here are some of the most common ways raycasts are used in games:

This grappling hook mechanic from The Legend Of Zelda: Link's Awakening could be using raycasts to find a valid surface to attach to.
Link using a grappling hook in The Legend Of Zelda: Link's Awakening
Become an Indie Gamedev with GDQuest!

Don't stop here. Step-by-step tutorials are fun but they only take you so far.

Try one of our proven study programs to become an independent Gamedev truly capable of realizing the games you’ve always wanted to make.

Nathan

Founder and teacher at GDQuest
  • Starter Kit
  • Learn Gamedev from Zero
Check out GDSchool

You're welcome in our little community

Get help from peers and pros on GDQuest's Discord server!

20,000 membersJoin Server

Contribute to GDQuest's Free Library

There are multiple ways you can join our effort to create free and open source gamedev resources that are accessible to everyone!