Hit when Body_Entered not working. How Can I Make Things Disappear When Interacted With?

4.3 Godot Version

I have two “groups” for the player to interact with in my 2D game. “Mob” I want to kill the player when one touches the player and “Mob_2” that I want to disappear when when the player touches one of them. Each mob and the player all have their own scene and script.
This is what I have, but it’s not working. The ‘player’ does not interact with either mob. “Mob” should disappear when hit by ‘player’, but ‘player’ should disappear and the game should end when hit by “mob_2”.
Here is the code for “Main”

extends Node

@export var mob_scene: PackedScene
@export var mob_2_scene: PackedScene
var score



func _ready():
	randomize()


func game_over():
	$ScoreTimer.stop()
	$MobTimer.stop()
	$HUD.show_game_over()
	$Music.stop()
	$DeathSound.play()


func new_game():
	get_tree().call_group("mobs", "queue_free")
	score = 0
	$Player.start($StartPosition.position)
	$StartTimer.start()
	$HUD.update_score(score)
	$HUD.show_message("Get Ready")
	$Music.play()


func _on_MobTimer_timeout():
	# Create a new instance of the Mob scene.
	var mob = mob_scene.instantiate()
	var mob_2 = mob_2_scene.instantiate()

	# Choose a random location on Path2D.
	var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
	mob_spawn_location.progress_ratio = randf()

	# Set the mob's direction perpendicular to the path direction.
	var direction = mob_spawn_location.rotation + PI / 2
	var direction_2 = mob_spawn_location.rotation + PI / 19

	# Set the mob's position to a random location.
	mob.position = mob_spawn_location.position
	mob_2.position = mob_spawn_location.position

	# Add some randomness to the direction.
	direction += randf_range(-PI / 4, PI / 4)
	mob.rotation = direction
	direction_2 += randf_range(-PI / 3, PI / 5)
	mob_2.rotation = direction_2

	# Choose the velocity for the mob.
	var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
	mob.linear_velocity = velocity.rotated(direction)
	var velocity_2 = Vector2(randf_range(100.0, 200.0), 0.0)
	mob_2.linear_velocity = velocity_2.rotated(direction)

	# Spawn the mob by adding it to the Main scene.
	add_child(mob)
	add_child(mob_2)


func _on_ScoreTimer_timeout():
	score += 1
	$HUD.update_score(score)


func _on_StartTimer_timeout():
	$MobTimer.start()
	$ScoreTimer.start()

Here is the code for “Player”

class_name Player extends Area2D

signal hit

@export var speed = 400 # How fast the player will move (pixels/sec).
var screen_size # Size of the game window.


func _ready():
	screen_size = get_viewport_rect().size
	hide()


func _process(delta):
	var velocity = Vector2.ZERO # The player's movement vector.
	if Input.is_action_pressed("move_right"):
		velocity.x += 1
	if Input.is_action_pressed("move_left"):
		velocity.x -= 1
	if Input.is_action_pressed("move_down"):
		velocity.y += 1
	if Input.is_action_pressed("move_up"):
		velocity.y -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position.x = clamp(position.x, 0, screen_size.x)
	position.y = clamp(position.y, 0, screen_size.y)

	if velocity.x != 0:
		$AnimatedSprite2D.animation = "right"
		$AnimatedSprite2D.flip_v = false
		$AnimatedSprite2D.flip_h = velocity.x < 0
	elif velocity.y != 0:
		$AnimatedSprite2D.animation = "up"
		$AnimatedSprite2D.flip_v = velocity.y > 0


func start(pos):
	position = pos
	show()
	$CollisionShape2D.disabled = false


func _on_Player_body_entered(_body):
	if _body.name is mob_2:
		hide() # Player disappears after being hit.
		emit_signal("hit")
	# Must be deferred as we can't change physics properties on a physics callback.
		$CollisionShape2D.set_deferred("disabled", true)

Here is the code for “Mob”

class_name Mob extends RigidBody2D


func _ready():
	var mob_types = Array($AnimatedSprite2D.sprite_frames.get_animation_names())
	$AnimatedSprite2D.animation = mob_types.pick_random()

func _on_visible_on_screen_notifier_2d_screen_exited():
	queue_free()


func _on_mob_2_body_entered(_body):
	if _body.name is Player:
		hide() # Player disappears after being hit.
		emit_signal("hit")
	# Must be deferred as we can't change physics properties on a physics callback.
		$CollisionShape2D.set_deferred("disabled", true)

Here is the code for mob_2

class_name mob_2 extends RigidBody2D
signal hit


func _ready():
	var mob_types = Array($AnimatedSprite2D.sprite_frames.get_animation_names())
	$AnimatedSprite2D.animation = mob_types.pick_random()

func _on_visible_on_screen_notifier_2d_screen_exited():
	queue_free()

And here is the last section

extends CanvasLayer

signal start_game


func show_message(text):
	$MessageLabel.text = text
	$MessageLabel.show()
	$MessageTimer.start()


func show_game_over():
	show_message("Game Over")
	await $MessageTimer.timeout
	$MessageLabel.text = "Delete the Emails!"
	$MessageLabel.show()
	await get_tree().create_timer(1).timeout
	$StartButton.show()


func update_score(score):
	$ScoreLabel.text = str(score)


func _on_StartButton_pressed():
	$StartButton.hide()
	emit_signal("start_game")


func _on_MessageTimer_timeout():
	$MessageLabel.hide()

What am I doing wrong???

Player inherits from Area2D, which in turn does not inherit from PhysicsBody2D. Your code presumably looks out for bodies entering other bodies, but should probably look for areas entering bodies/other areas.

So change _body to _area?

Yes, and also connect to the correct signal.

Thank you! This is what I have now, but I got an Error message.

Sorry, disregard what I said earlier. Mob should kill the player when the player touches it, right? If so:

class_name Mob extends RigidBody2D

func _ready():
	var mob_types = Array($AnimatedSprite2D.sprite_frames.get_animation_names())
	$AnimatedSprite2D.animation = mob_types.pick_random()

func _on_visible_on_screen_notifier_2d_screen_exited():
	queue_free()

func _physics_process(delta : float)->void:
	if has_overlapping_areas():
		var areas : Array[Area2D] = get_overlapping_areas()
		for area in areas:
			if area.is_in_group("Player"):
				player.visible = false # Or however you want to handle the game over state.

Mob2 enemies should die when touched by the player. This can be done analogous to the code above, except using get_overlapping_bodies.

Note that you need to add the player and both mob scenes to a group for this to work:

# Example on how to set groups. Image this is the player script. The same needs to be done for both `Mob` classes.

func _ready()->void:
	add_to_group("Player")

Thank you! This is what I’m looking at now.

Hi, im not 100% sure but this might work, maybe make sure your "func body_entered " is actually connected to the script? Like first disconnect the body entered signal, 2nd connect it again, and dont change the (body: Node2D): in the function, keep it like that, dont make it: (_body) because that’s probably the cause

And just add that queue_free() thats in the photo

And if it still isnt colliding, you orobably just have to change your collision mask or layer