How to make something happen when a body collides 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.

I tried

extends Kinematicbody2D

func _ready():
   set_process(true)
   func _process(delta):
         if(get_collider() == Kinematicbody2D): # I even tried if(get_collider() == "enemy")
         print("Ouch!")
         queue_free()

And this

#all previous code  except for process function
func _process(delta):
   if(is_colliding()):
     if(get_collider() == Kinematicbody2D):
        print("Ouch!")
        queue_free()

For Rigidbody2D I use get_colliding_bodies ( ) and then check if it contains the specific body. But I don’t know about Kinematicbody2D.

Anutrix | 2017-04-11 08:42

Did you try this:

    #all previous code  except for process function

    func _process(delta):
       if(is_colliding()):
         if(get_collider() == get_node("enemy")):
            print("Ouch!")
            queue_free()

where enemy is name of specific node with which current body is colliding.

Anutrix | 2017-04-11 08:45

Yes I tried that but the enemy node is not in the player scene so I wrote this get_tree().get_root().get_node("enemy") it worked but when the player touches other objects the queue_free() action runs. So I tried implemeting it at the enemy script since the player will be the one affected I wrote

if(is_colliding() == get_tree().get_root().get_node("player")):
   print("Ouch!")
   get_tree().get_root().get_node("player").queue_free()

Godot can’t even find the player scene, any ideas on how to fix that

Dava | 2017-04-11 18:23

:bust_in_silhouette: Reply From: eons

KinematicBody only reports collisions after using move, is used to prevent overlaps more than to detect collisions (but gives you some information to do something about it).

You need to find another way to detect collision/overlap.

Example:
To hurt the player with a bullet make the bullets Areas/Rigid bodies and, on body_enter signal, ckeck if the body can be damaged and tell the body to get damage (having bullets monitoring may be good or bad depending on the game).

Other option could be to add an area to the player on a different mask than main body layer, used to detect the objects that can do damage, if something is detected by that area, tell the main body to get hurt.

+1, use areas :slight_smile:

Nuno Donato | 2017-04-11 17:50

How do you make a node Area/Body and how do you add area on a different mask

Dava | 2017-04-11 18:26

You add Area nodes like you add any other node, look at the kinematic character demo, the princess is an Area2D.

CollisionObject nodes (areas and bodies) have layer and mask for collision detection, layer is like where they are (detected) and mask is where they look for collisions/overlaps.

eons | 2017-04-11 21:24

So I did all that and now it works but even when the enemy’s area2d collides with other bodies, the code executes here’s the code

func _ready():
  get_node("area").connect("body_enter",self,"player_body")
  pass

func player_body(body):
     if(body.get_name() == "player"):
        print("Ouch!")
        qyeue_free()

Instead of the code being executed only when the enemy collides with the player, it exceutes when the enemy collides with anything, how to fix that?

Dava | 2017-04-12 18:02

If that code is on the enemy, the enemy area mask must be the same as the player body layer, if the mask is the same as all the other objects, will detect them everytime (because other bodies may pass through the area).

If the area detecting bodies is on the player, the area mask need to be on the same as the layers it monitors for damaging objects (you can use different layers for each type of enemy or a single layer and filter in another way,).


Some ways to use layers:
layer 1: solid map
layer 2: player
layer 3: enemies
layer 4: general damage environment
layer 5: instakill
layer 6: immune bullets

And masks:
Player: 1 (movement), 3, 4, 5, 6 (for damage)
Enemies: 1, 4 (player detect enemy already)


Could be more simple (all damage on one layer and use groups) or more complex depending on the design, you have 20 layers to play with.

eons | 2017-04-13 01:00