How do you make area only collide with a specific body

: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.

So in my previous post I had problem colliding area with bodies and with this code I was able to fix it (Thanks Zylann!)

extends Area2D

func _ready():
   connect("body_enter",self,"_on_body_enter")
   pass
 

func _input(event):
   if(event.is_action_pressed("ui_action")):
       queue_free()

func _on_body_enter(body):
        set_input_process(true)

But now I have another problem, the area2d is inside a staticbody2d object and whenever I click ui_action all the area2d gets destroyed, but I only want the area2d to be destroyed when the kinematicbody collides with it and then I press ui_action think of it like a person, item, and self, the person is the kinematicbody, the self is the Staticbody, and the item is the area2d, the item is in the self and when the player reaches the item, he/she picks it up with ui_action but right now no maker where the person is, when the ui_action gets pressed, since the item is already colliding with a body(the shelf) it gets destroyed, how can I get the _on_body_enter(body) to only work with kinematicbodies?

:bust_in_silhouette: Reply From: Zylann

There are several ways:

One way is doing this:

func _on_body_enter(body):
    if body extends StaticBody2D == false:
        set_input_process(true)

Or this:

func _on_body_enter(body):
    if body.get_name() == "Player":
        set_input_process(true)

Which is a bit inefficient because the test could be triggered a lot of times for nothing and waste CPU, but allows much flexibility and should not be too bad on games with few collisions.


A more efficient way is to leave the code you already have, and use physics layers and masks.

Put your bodies in an additional layer, and make sure you area only detects that layer. You can set these layers in the inspector.
So your area2d would have this Collision/Mask:

_ X _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _

By default the first checkbox is checked, which will detect your staticbodies because they are in layer 1 by default. On your area, if you uncheck mask 1 and check mask 2 for example, areas will detect only layer 2.
So whatever enters the areas has to be in layer 2 to be detected, so have the second box checked in their Collision/Layers.

Layers are an efficient way to tell which objects interact with which in the physics engine, too bad the tutorials don’t mention them, only the scripting doc does: Area2D — Godot Engine (latest) documentation in English

Wow, that was fast! I will try this and send a feedback if I have trouble.

Dava | 2017-04-06 18:46

The second method worked, thanks!

Dava | 2017-04-07 14:48