Quick answer: Set contact_monitor = true AND max_contacts_reported to a non-zero value. Both default off — without them, contact queries and signals stay empty.
A RigidBody2D crate should detect what it’s resting on, but get_colliding_bodies() returns an empty array and body_entered never fires.
Two Settings, Both Required
func _ready():
contact_monitor = true
max_contacts_reported = 8 # > 0, sized to expected contacts
- contact_monitor: enables contact tracking at all. Off by default for performance.
- max_contacts_reported: the buffer size. Zero means “report nothing” even with the monitor on.
Then the Signals Work
body_entered.connect(_on_body_entered)
func _on_body_entered(body):
if body.is_in_group("hazard"):
take_damage()
With both settings on, body_entered / body_exited and get_colliding_bodies() all populate.
Size the Buffer Right
If a body can touch many things at once (a crate in a pile), max_contacts_reported caps how many you see. Set it to the realistic maximum — too low silently drops contacts.
Verifying
Drop the crate onto the floor. get_colliding_bodies lists the floor. Stack crates — each reports its neighbors up to the buffer size.
“Contact monitoring needs the flag and a non-zero buffer. Either alone reports nothing.”
Only enable contact_monitor on bodies that actually query contacts — it’s off by default because it costs CPU per body.