How to make a body collide with area2d

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dava
:warning: Old Version Published before Godot 3 was released.

How do you make a body (Rigidbody, Staticbody, Kinematicbody) collide with area2d I tried tried connecting the scene like get_tree().get_root().get_node("Area2D").connect("body_enter,self,"on_body_enter") but that did not work, I am trying to get the body to be colliding with an Area2D then when the player clicks the action button, the area2d disappears and score gets added, any idea on how to do that?

If you want to apply physics after a collision, you might want to use another physics node.
Try reading the docs’ tutorial.

Otherwise, if you just wanna check if they’re overlapping, you can use the signal on_area_enter and write your code in there.

DodoIta | 2017-04-03 07:50

I guess you just want to detect collision, not necessarily apply physics, right? (like a trigger)
body_enter is the correct one to use with bodies (on_area_enter is for areas, not bodies).

However, how did you implement the on_body_enter function?
When you say “didn’t worked”, what actually happened? Any error?

Zylann | 2017-04-03 12:53

No errors, the game runs but either the player no longer functions or the code responsible for the area2d doesn’t get executed at all

Dava | 2017-04-03 16:14

Any ideas on how to get nodes from other scenes?

Dava | 2017-04-03 16:15

Hold on, one question at a time^^
How did you implement the on_body_enter function? Which code did you write?

(For your second question, you can do a search, other users asked similar questions before: Search results for access nodes from other scenes - Godot Engine - Q&A)

Zylann | 2017-04-03 17:35

I actually meant on_area_enter I don’t have my computer so I am writing this off head

func _ready():
    get_tree().get_root().get_node("Area2D").Connect("on_area_enter",self,"body_enter")
    pass

func body_enter(body):
    If(Input.is_action_pressed("ui_action"):
         get_tree().get_root().get_node("Area2D").queue_free()

This is the code but it doesn’t work. Any ideas on how to fix it?

Dava | 2017-04-04 03:53

:bust_in_silhouette: Reply From: Zylann

on_area_enter will only detect other Area2Ds. If you want to detect bodies, you must use the body_enter signal.

extends Area2D

func _ready():
	connect("body_enter", self, "on_body_enter")

func _on_body_enter(body):
	print("Body entered the area")

However that will trigger only one time when the body enters the area, so also testing input won’t work because the player will most likely press the button after entering the area. You could set a boolean to remember you entered or left an area, but there is a simpler way.

The following is an alternate way of doing it, assuming your character also has an Area2D for picking/destroying stuff:

extends Area2D

func _ready():
	set_process(true)

func _process(delta):
	# On each frame
	
	# If button is pressed
	if Input.is_action_pressed("ui_action"):

		# Destroy every colliding areas
		var colliding_areas = get_overlapping_areas()
		for area in colliding_areas:
			area.queue_free()

The second code looks interesting, will it work for bodies (Kinematicbody, Rigidbody)

Dava | 2017-04-04 18:34

Well, the problem with bodies is that you usually can’t enter them, because they are solid, so your approach requiring to press a button won’t work.

You can use the second method if you have an area 2D entering other areas, and it will also detect bodies if you use get_overlapping_bodies() instead of get_overlapping_areas().
But for a body colliding with other bodies, the approach will be different since they can’t overlap (maybe using get_collider() if is_colliding() gets true? Or using signals)

Zylann | 2017-04-04 19:36

I got it to work with the first code! but now I have another problem…

Dava | 2017-04-06 18:00