Possible to detect multiple collisions with RayCast2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jarlowrey

I don’t see an option for this in the API - RayCast2D — Godot Engine (3.0) documentation in English - but I want to iterate over every object intersecting my Raycast instead of just the first collided object. Is that possible?

:bust_in_silhouette: Reply From: SIsilicon

Algorithms ahoy!

#ray is your RayCast2D node.

var objects_collide = [] #The colliding objects go here.
while ray.is_colliding():
    var obj = ray.get_collider() #get the next object that is colliding.
    objects_collide.append( obj ) #add it to the array.
    ray.add_exception( obj ) #add to ray's exception. That way it could detect something being behind it.
    ray.force_raycast_update() #update the ray's collision query.

#after all is done, remove the objects from ray's exception.
for obj in objects_collide:
    ray.remove_exception( obj )
    

Nice! Thanks!

jarlowrey | 2018-05-09 01:21

Seems like it should work but I’m having a strange issue. Using this code, once the entity it’s colliding with dies (and calls queue_free()) the game freezes without error codes. Inserting print() statements does not print anything to console. Changing the while conditional to check the value of get_collider results in a freeze at the first collision instead. Very strange.

jarlowrey | 2018-05-09 01:38

Got it to work by removing code from a helper function and moving it into _physics_process. Then checking if the get_collider is !=null when actually using it. Thanks!

jarlowrey | 2018-05-09 01:50

This worked for me, albeit with a strange quirk: if I have a tilemap, and the collision ray collides with the tilemap, the while-loop ends up looping forever. It seems that - despite adding the tilemap as an exception to the collider - it still collides.

I don’t know if this is a Godot bug or something specific about my setup; in the meantime, you can work around this, by simply adding something like this in the while loop:

if obj in objects_collide: break

nightblade9 | 2022-01-09 14:25

1 Like