Odd Player detection behaviour on Disabled CollisionShape2D

Hi everyone!

I am trying to create a simple “Spawner” that instances a given number of given mobs when the player enters a designated area.

It works perfectly BUT when i came to make them “single use” a problem arised: i made a flag called is_single_use, than when the player enters the area i made so that the logic of the spawner turns the collision shape “Disable” to true but for some reason it keeps detecting the player on re-enter.
I controlled in the Remote and with visible collision shapes on so i can confirm that it actually get turned off correctly when the player enters it for the first time.
If i manually set it as disabled FROM THE REMOTE it doens’t detect the player and therefore works as intended.

Yet disabling it from the logic after the first detection turns it off, but the player still gets detected every time

I will post my code for the spawner here, if anyone has some idea of what i am doing to create this odd behaviour the help would be very appreciated

#independant spawner area, drag and drop, specify mobs in enum
extends Area2D

@export var FlyingEyeMob: PackedScene
@export var GoblinMob: PackedScene

@export var mob_number : int
@export_enum("FlyingEyeMob", "GoblinMob") var mob_type #export the type of mob this spawn area handles
@export var spawner_wait : float = 0.0 #lenght of timer between spawns
@export var is_single_use : bool = true #used to make the spawn area single use

@onready var spawn_detector = $DetectionZone #My CollisionShape2D
@onready var spawner = $SpawnPoint #To get coordinates for the mob
@onready var player = Global.playerBody #Gets player from global script


#detects the player and spawn the given number of selected enemy each time the player enters the area
func _on_body_entered(body: Node2D) -> void:
	if body == player:
		if is_single_use: #disable detection on single use SpawnArea
			spawn_detector.disabled = true
		if mob_number == 0: #spawns a single mob of mob_type
			if mob_type == 0:
				var mob = FlyingEyeMob.instantiate()
				add_sibling(mob)
				mob.global_position = spawner.global_position
			elif mob_type == 1:
				var mob = GoblinMob.instantiate()
				add_sibling(mob)
				mob.global_position = spawner.global_position
		elif mob_number > 0: #spawn mob_number of mob_type
			for i in mob_number:
				if mob_type == 0:
					var mob = FlyingEyeMob.instantiate()
					add_sibling(mob)
					mob.global_position = spawner.global_position
					await get_tree().create_timer(spawner_wait).timeout
				elif mob_type == 1:

You have to set disabled using set_deferred
From Godot Docs:

bool disabled = false

void set_disabled(value: bool)
bool is_disabled()

A disabled collision shape has no effect in the world. This property should be changed with Object.set_deferred.

Try this first and see if the issue is fixed.

1 Like

it worked like a charm, thank you very much for the help, it was much appreciated AND will be very useful to know in the future!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.