Unable to detect collision between two Kinematic Bodies

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

Hi, I am new to Godot and game development in general so please forgive any newbie mistakes. I am currently working on a simple space shooter game. I have uploaded the code to Github.

The problem is that I have two KinematicBody2D objects : One is user’s spaceship and other is enemy ship. They both have rectangle collision shape. But the collision is only detected when the ships collides on side, not when they are in front of each other.

Also please look at the project and suggest how I can improve.

:bust_in_silhouette: Reply From: mateusak

A kinematic body wont detect collisions against another kinematic body. I recommend you to read the Physics introduction in the wiki. Can be easily fixed with an Area2D or a RayCast2D.

This Physics introduction is now here.

idbrii | 2022-12-16 21:09

:bust_in_silhouette: Reply From: genete

From a quick look to the code I see that you try to detect collision in both bodies. I have one game working well with collision between two KinematicBodies but I only test the collision in one of the fixed process. I do it on the enemy side. Once I get a collision event, then I check if the collider is a player type using the extends keyword. Then I get the collider node and call whatever you want to do with it.

Maybe that’s your problem, the collision of the spaceship happens before the enemy collision and then (because you move it) the other collision doesn’t happen.

:bust_in_silhouette: Reply From: paco

At least in Godot 3.0, KinematicBodies detect collision via move_and_collide() or move_and_slide(), NOT by the signals that all the other bodies emit (like body_entered).

Aside from the docs, a good explanation can be found here: Godot 3.0: Using KinematicBody2D · KCC Blog

The point of KinematicBodies is the physics engine knows about them, but they are controlled by the code, i.e. player input or something other than real-time physics.

If you wanted real-time physics, like a cannon ball that falls due to gravity and rolls around, you would want a RigidBody. But if you want a bullet that simply shoots forwards, you want a KinematicBody that might look like this:

extends KinematicBody2d

var direction = Vector2(-100,0) # Shoot to the right at 100px/sec

func _physics_process(delta): # Used to be _fixed_process(delta) in
    # Note, move_and_slide() should NOT multiply delta, that is managed internally as it accommodates sliding.
    # If this was a player, we'd be polling the Input to determine the move direction.
    collisions = move_and_collide(direction * delta) 
    if collisions:
        pass # Look at what has been hit and behave appropriately, like dust fx for hitting a wall or damaging an enemy

Doing it this way, vs simply placing the obj at a new location, is important because if you don’t use the move_and_collide/slide, it’s possible for something to be moving too fast and go through a wall. And if your situation does not require real-time physics, using a RigidBody is a computational waste and you speed time undoing all the features you get from it.

I know this post is a few years after the original, but I was also initially confused and want to help out anyone else who also finds this in the top search results.

I found that this does not work for the player while collided by others aside.
It works when the player collides with other KinematicBody (generally, anything with a CollisionShape2D) with the initiative.

SpkingR | 2018-11-18 00:13