Collision detection isn't working

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

Hello!

I’m having some rather strange issues with the collision detection in a top-down 2D game I’m trying to program. You see, I’m trying to make the player teleport a few steps forward, ignoring walls in the process. The player is a KinematicBody2D, though, so I can’t use the built-in movement methods because they detect walls.
I figured a good idea would be to have an object permanently 3 tiles in front of the player, and when I want to warp, just set the player’s position to that object if it isn’t inside a wall, like this:

if(!target.is_colliding()):
	user.set_global_pos(target.get_global_pos())

Above, “target” is another KinematicBody2D, a child node of the player with another rectangle collider that exactly matches that of the player.
The problem is that

!target.is_colliding()

ALWAYS returns true, no matter where the target is.
(Here, I have given the target an ugly square graphic and made hitboxes visible. And yes, it returns true.)
Why does this even happen

I even tried using the method

target.test_move(Vector2(0,0))

instead of is_colliding, and it shouldn’t make a difference, but in this case it works. Sometimes. Some other times, like on the image above, it also teleports you into a wall.

I’ve searched forums like crazy looking for an answer but I can’t find any reason why this would be happening. Can anyone help me?

Are the player walking on a tilemap?

If yes, you should check if the target is the tilemap background and exclude it (mask)

puppetmaster- | 2016-12-06 18:09

The player is walking on a tilemap but movement is not restricted to tiles, it’s free.
I’m not exactly sure what you mean, but:

This is what the mask of the tilemap looks like, and the one for the target is exactly the same. Only the wall tiles have any sort of collision (a StaticBody2D).

HikaruAikawa | 2016-12-06 18:18

have you tried using a RigidBody instead of the Kinematic ? I’ve had so troubles in the past with kinematics and collisions.

MrMonk | 2016-12-06 19:02

If you only want overlap detections you can use an Area2D instead or use one of the Tilemap methods to check the tile type at a specific (world to tilemap) position and check if is one of the allowed tiles.

eons | 2016-12-06 19:04

:bust_in_silhouette: Reply From: Warlaan

This is a common misunderstanding. The is_colliding() function doesn’t return whether or not the KinematicBody2D is currently colliding with something, it merely returns whether the last call to move() was able to move all the way. If you are using the KinematicBody2D the way it was originally intended this will not make a difference but in cases like yours it’s crucial.

If you want to be able to detect if there is something inside a given area you need to use an area node instead of a kinematic body.
But generally speaking you can simply use move() if you want the object to collide and translate() if you want it to ignore collisions.

Thank you very much for your answer! It looks like using an Area2D and the method get_overlapping_bodies is exactly what I need.

HikaruAikawa | 2016-12-06 19:20