Collision Layer vs. Mask

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

Hello! I’m working on a platformer battle game where I have a player, weapon, and enemy. I want to have:

  • The Enemy hurt by the Weapon, not the player
  • The Player hurt by the Enemy, not the weapon
  • The weapon doesn’t have health so that’s not a problem.
    I noticed in the Inspector tab for an Area2D that there is a collision layers and mask area. I read the description and it seems like I could just mask the player in a enemy layer and mask the enemy on a weapon layer but it doesn’t seem to work - The player and the enemy are getting hurt simultaneously no matter what I do. Should I do something else (it’s not possible to make what I want, work with collision layers and masks), or is there an easy solution using collision layers and masks that I’m missing.
:bust_in_silhouette: Reply From: njamster

If the player (object A) collides with the enemy (object B), the enemy (object B) will also collide with the player (object A). Check out the documentation:

A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans.

I’d recommend you use groups, add your player-scene to a group “Players” and your enemy-scenes to a group “Enemies”. This way you can easily differentiate between the two in a call to _on_Area2D_area_entered (if your scenes are Area2D-nodes) / _on_Area2D_body_entered (else) by checking for those groups:

Player.gd

var hp = 10

func _on_Area2D_body_entered(body):
	if body.is_in_group("Enemies"):
		hp -= 2

Enemy.gd

var hp = 5

func _on_Area2D_body_entered(body):
	if body.is_in_group("Enemies"):
		print("I told you homeboy: You can't touch this!")