Collision between KinematicBody2D types is seemingly inconsistent

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

Hello, I am fairly new to Godot and game development in general, and i’m making a top-down shooter as my first game in the engine. For my first enemy, i am having a KinematicBody2D to chase the player(who is also a KinematicBody2D) and deal damage when colliding with it. This is the code for the enemy’s AI:

extends "res://AI.gd"

func run():
	if initialized:
		var direction = body.global_position.direction_to(player.global_position)
		direction *= actor_values.speed
		body.move_and_slide(direction)
	
	
		for i in body.get_slide_count():
			var collision = body.get_slide_collision(i)
			if collision.collider.is_in_group("AnimeHater"):
				if collision.collider.has_method("handle_hit"):
					collision.collider.handle_hit(actor_values.strength)

and this is how the player is programmed to take damage:

func handle_hit(strength):
if invul_timer.is_stopped():
	print("damaged!")
	invul_timer.start()
	animation_player.play("Damaged")
	health.current_health -= strength 
	health.current_health = clamp(health.current_health, 0, 100)
	health_label.text = ("Health: " +str(health.current_health))
	if health.current_health == 0:
		die()

The damage on the player does occur when he is first touched, but if the player stays still, sometimes he takes damage as soon as the invulnerability is over (which is the intended behaviour), and sometimes the next time he takes damage is seemingly random, as shown in this video:

What can i do to have the player character always being damaged as soon as his invulnerability period is over?

:bust_in_silhouette: Reply From: betauer

The problem here is you are only detecting collisions from move_and_slide() results, which is correct if you want to detect walls or the ground but it forces you to move every time to keep detecting collisions. In this case, where you and the enemy could stay still without moving, I would recommend you to use Area2D, where you can connect it with two signals: body_entered and boy_exited. Listening them you can detect if the enemy is overlapping your player when the invulnerability timers finished and damage it again.