how do I check if a specific object is overlapping an Area2D every frame?

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

I know it’s possible to code something like this

func _on_Area2D_body_entered(body):
if body.is_in_group("somegroup"):
    print("collisions! but once...")

but the above code checks this once, I want to check it every frame.

:bust_in_silhouette: Reply From: Ninfur

You can use either the get_overlapping_bodies() or overlaps_body(body: Node) method on the area.

func _process(delta):
    for body in area.get_overlapping_bodies():
        if body.is_in_group("somegroup"):
            print("collisions!")

You can quickly find all available methods and properties in the documentation that is built into the editor.
Simply press F1, search for “Area2D” and hit enter.

It may be better to use it in _physics_process() because that’s when the overlapping bodies are updated.

Necco | 2022-05-02 20:29

:bust_in_silhouette: Reply From: nightblade9

Area2D has a get_overlapping_bodies method. According to the docs:

For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.

I personally use a different approach, which appears to work well, and seems to be more performant:

  • Keep a list of overlapped bodies in a local variable like _overlapping
  • Add a signal to body_entered that appends the body to _overlapping
  • Add a signal to body_exited that removes the body from _overlapping

Each frame (in _process_physics), act on everything in _overlapping, e.g.:

func _process_physics(delta):
  for body in _overlapping:
    body.take_damage()