Detecting collisions between two separate scenes with body_entered

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

In a project I’ve been working on I have been trying to set up an ‘aggro radius’ for another entity in which a specific function will be ran if a certain body enters the radius.

In this scenario I have two entities:

A player with it’s own collision shape in its tile.
An enemy with a large collision radius.

I have made sure that both of these CollisionShape2D’s are on the same collision layer.

Within the enemy, attached to the Area2D (the aggro radius) I have this script:

extends Area2D

func _ready():
	connect("body_entered", self, "_on_body_enter")

func _on_body_enter(body):
    print("Test" + body.name)

Since the player’s collision shape is a body I would assume that this would work but it doesn’t. Is there anything extra I would need to do for this implementation?

As a follow up question - what counts as a body for body_entered? Shouldn’t two Area2D’s with children CollisionShape2Ds on the same layer count?

Carcanken | 2021-03-19 23:28

With respect to what counts as bodies for collision, the nodes that have the word “Body” in their name count for body_entered(). I’m not entirely certain why it’s set up like that. But the reason could be that the physics server and the system for detecting collisions are related.

Ertain | 2021-03-19 23:40

1 Like
:bust_in_silhouette: Reply From: Mrpaolosarino

I have a similar approach but don’t use signals though it works.

func physics_process(delta):
         var Bodies = $Area2d.get_overlapping_bodies()
         for b in Bodies:
         if b.name == "Player":
                 print("Go to player")

Attach this to your area 2d if you don’t want the hassle of signals
If your Player uses another area2d to get enemy aggressive then change var Bodies = get_overlapping_bodies() into var Areas = get_overlapping_areas()

Also the b.name = "Player refers to the name of your player area 2d or kinematic body

Thank you for this solution!

I have a slight worry about it though - is it not much worse performance wise to check for colliding bodies every physics_process call rather than to wait for a signal?

Carcanken | 2021-03-20 06:03

It depends on you. I personally use this because of it’s versatility. On the performance on the other hand, it is not fps eater. I think the most fps eater in your game is light and post procrssing

Mrpaolosarino | 2021-03-20 06:50

If the code frequently checks for collisions with get_overlapping_bodies(), then the performance will suffer.

Ertain | 2021-03-20 09:07

Well, it’s up to you, In my game personally, I use my solution but I didn’t see any drastic performance suffer. Either way, you can use the signal method or collision check.

Mrpaolosarino | 2021-03-20 09:21

If performance suffers, on the other hand, you can just check the collision object surrounding if you press a certain key. I think this is the key aspect of reducing it’s fps drop

Mrpaolosarino | 2021-03-21 07:10

:bust_in_silhouette: Reply From: Carcanken

The solution for this was to simply check for the area being entered rather than the body since I was only testing if two Area2D’s collided essentially. Seems it was a dumb mistake.

extends Area2D

 func _ready():
     connect("area_entered", self, "_on_area_enter")

 func _on_area_enter(area):
     print("Test" + area.name)
1 Like