Differentiate Tile Collisions
I always use the signal body_entered
to detect collisions. This signal has a parameter with the body of the collision. But here’s the problem: if it collides with the shape of a tile it will always return the TileMap
object, independently of which tile we collide with.
In my case I wanted to detect the house where the villager is, so his projectiles don’t collide with it but can still collide with other tiles like trees:
The solution I found is to use the body_shape_entered
signal instead of body_entered
. body_shape_entered
has a parameter with the RID
of the body. As it turns out, the RID
is unique for each shape.
Now we need a way to get the RID
of the tile we want to avoid colliding with. We can do it attaching an Area2D
to the window villager:
Make sure the Area2D
mask has the only the bit of the tile shape you want it to collide with.
Then, in the script of the villager, we can connect the body_shape_entered
signal in the _ready
funcion and store the RID
of the house on a variable for later use:
And that’s it, now we only need to make the projectile hitbox ignore this RID
. In my case I created an array of rids to exclude on the hitbox script. Replace the body_entered
signal of the hitbox for the body_shape_entered
and just return if the RID
of the body the hitbox collides with is in the exclude array:
When the villager throws the projectile, we add the house rid to the projectile exclude_rid
array:
Here’s the final result:
The house and the tree are tiles that have the same collision layer. The projectile collides with the tree but not with the house. Nice!