Kinematic2d collision detection not working in some cases

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

Problem -

See the game description and game code below the problem statement to know what I want to ask. Thank you.

The collision are working fine when I collide my red with green by moving opposite to direction of green’s movement and touching it.

However if I move in the same direction of green’s movement and collide with it it doesn’t get destroyed, and it happens tht I am just pushing the green block.
And I want to actually destroy it coming from any direction.

Game description -

Basically, I have two rectangular bodies(kinematic2d) with rectangular sprites and collisionshape2d covering full. Let me call them red and green. Red being user always positioned at mouse position and green being enemies coming at random on screen with different speeds and positions.
Gem screenshot

Ignore the violet color ones for now.

Code-

For the green I have used collision masks and layers correctly so that it ignores collision with each other but collides with red and code snippet being-

func _fixed_process(delta):
if(is_colliding()==true):
	queue_free()

Full code of green if you wish to see-

    #script - green rectangle object
extends KinematicBody2D

var velocity = Vector2()

func _ready():
	var x = rand_range(0,512)
	var y = rand_range(0,256)
	var x_sp = rand_range(-150,150)
	var y_sp = rand_range(-150,150)
	velocity.x = x_sp
	velocity.y = y_sp
	set_pos(Vector2(x,y))
	add_to_group("grp_green")
	set_fixed_process(true)
	pass

func _fixed_process(delta):
	if(is_colliding()==true):
		queue_free()
	var motion = delta*velocity
	move(motion)
	var curr_speed = motion
	var curr_pos = get_pos()
	if(curr_speed.x >= 0 && curr_speed.y>=0):
		if(curr_pos.x >= 512): 
			set_pos(Vector2(0,curr_pos.y))
		if(curr_pos.y >= 256):
			set_pos(Vector2(curr_pos.x,0))
	elif (curr_speed.x <= 0 && curr_speed.y>=0):
		if(curr_pos.x <= 0): 
			set_pos(Vector2(512,curr_pos.y))
		if(curr_pos.y >= 256):
			set_pos(Vector2(curr_pos.x,0))
	elif (curr_speed.x <= 0 && curr_speed.y<=0):
		if(curr_pos.x <= 0): 
			set_pos(Vector2(512,curr_pos.y))
		if(curr_pos.y <= 0):
			set_pos(Vector2(curr_pos.x,256))
	elif (curr_speed.x >= 0 && curr_speed.y<=0):
		if(curr_pos.x >= 512): 
			set_pos(Vector2(0,curr_pos.y))
		if(curr_pos.y <= 0):
			set_pos(Vector2(curr_pos.x,256))
	pass

And code for red-

    #script - me to the cursor position
extends KinematicBody2D

func _ready():
	set_fixed_process(true)
	pass

func _fixed_process(delta):
	set_pos(get_global_mouse_pos())
	pass
:bust_in_silhouette: Reply From: eons

Collisions on kinematics only works correctly if you move them with move or move_to.

When I use the following in code of red, green doesn’t get destroyed upon collision, I don’t know why.

if(is_colliding()):
get_collider().queue_free()

I wrote this on mobile so don’t mind the syntax just answer why this would not work.

iammangod96 | 2016-10-16 15:31

Is not triggering the collision because you never move() the body.

Change your set_pos to move or move_to.

eons | 2016-10-16 16:02

:bust_in_silhouette: Reply From: iammangod96

So finally I solved the issue myself and made following two conclusions over the problem -

  1. Kinematic2D objects don’t always require move and move_to for collision checking. Using set_pos in _fixed_process(delta) works perfectly.

  2. The solution to my problem was reducing the collision margin in the inspector panel of kinematic2D object. Higher collision margin made collision detection not possible.

Thank you. Your Solution with collision margin helped me solve different problem.

I had a problem with two players, both KinematicBody2D colliding and not handling the physics event properly.

Where sometimes it one would detect the other or other times both detected each other.

By lowering the collision margin in the inspector window of the KinematicsBody2D I was able to fix the problem. I made it from 0.08 to 0.01.

Then only one of the two bodies was detecting the other. Namely the one which started it.

*Only basic testing was done so do your own tests on this as well.

zex | 2021-06-06 14:16