Spawn multiple enemies at once using one enemy

Godot Version

4.6.2

Question

I am trying to figure out how to spawn multiple enemies at once using one enemy node. Is there any way i can do this in my code or do i need to add a new node and redo my spawn/respawn code entirely? Sorry if this is a stupid question, i am pretty new to godot.

extends CharacterBody2D

@export var spawn_position = Vector2(41, -79)
var respawn_pos: Array = [
	Vector2(-26, -79), 
	Vector2(0, -79), 
	Vector2(41, -79)
	]
#@export var enemy_id: int
@export var respawn_time := 3.0

@onready var sprite: Sprite2D = $Sprite2D
@onready var collision_shape: CollisionShape2D = $CollisionShape2D
@onready var timer: Timer = $Timer


var invulnerable := false
var is_dead = false
var can_attack := true
var healing = false
var heal_cooldown = true
var health
var hit_cooldown = false
var original_layer: int
var original_mask: int
var speed = speedy

func _ready():
	original_layer = collision_layer
	original_mask = collision_mask
	door = get_tree().get_first_node_in_group("door")
	#sets spawn location
	if GameState.on_main_menu:
		GameState.enemy_1_positions = position
	if not is_dead:
		if not GameState.is_game_starting:
			global_position = GameState.enemy_1_positions
		if GameState.is_game_starting:
			global_position = spawn_position
			GameState.is_game_starting = false
	move_and_slide()


func _deferred_restore():
	await _wait_for_enemies()
	restore_game_state()

		
func restore_game_state():
	if not GameState.has_saved_state:
		return

	for enemy in get_tree().get_nodes_in_group("enemies"):
		var id = enemy.get_instance_id()
		if id in GameState.enemy_1_positions:
			enemy.global_position = GameState.enemy_1_positions[id]


func disable_target():
	# Turn OFF target
	if is_dead:
		return
		
	GameState.money += 1
	GameState.kills += 1
	is_dead = true
	sprite.visible = false
	set_physics_process(false)
	collision_shape.set_deferred("disabled", true)
	await get_tree().physics_frame
	timer.start(respawn_time)
func _on_timer_timeout():
	can_attack = true
	if is_dead:
		
		var respawn_position = respawn_pos.pick_random()
		global_position = respawn_position

		# Restore collision settings
		collision_layer = original_layer
		collision_mask = original_mask

		# Reactivate visuals
		sprite.visible = true
		# Re‑enable collision SAFELY
		await get_tree().physics_frame
		collision_shape.set_deferred("disabled", false)
		set_physics_process(true)
		is_dead = false

@export var speedy: float = 100.0

var door: Node2D


func _physics_process(_delta):
	if door == null:
		return

	# Direction toward door
	var direction = (door.global_position - global_position).normalized()
	# Move enemy
	velocity = direction * speed
	move_and_slide()
	if sprite.visible == false:
		speed = 0
	if sprite.visible == true:
		speed = speedy
	GameState.enemy_1_positions = position


# enemy detects and attacks the door
	if door and global_position.distance_to(door.global_position) < 20:
		if can_attack:
			attack_door()
			Global.getting_hit = false

# enemy damages the door
func attack_door():
	Global.health -= 1
	#print("hit")
	can_attack = false
	timer.start(1.5) # attack cooldown time
	if Global.health <= 0:
		get_tree().change_scene_to_file("res://scenes/game_over.tscn")



func _wait_for_enemies():
	while get_tree().get_nodes_in_group("enemies").is_empty():
		@warning_ignore("redundant_await")
		await get

Do this for every enemy you want.

thank you!

Do you think you could explain a bit on how I would create an instance for an enemy?

In my case, it’s roaches as ‘enemies’; adapt as required for your Project…

# 'lv_' is 'local variable'
# 'lc_' is 'local constant'
# There is an 'Autoload' with the Global Variables, 'gv_'
# The 'Bug_Spaw_Poin' is in the Scene Tree; the bugs are spawned from there.

#const lc_numb_bugs_spaw = 1 # *** Test
const lc_numb_bugs_spaw = 10

var lv_random_turn = deg_to_rad(0)

@onready var lv_bug
@onready var lv_bug_scene = preload("res://Beasts/roac_brow.tscn")
	
func create_bug():
	for lv_numb_bugs in range(0,lc_numb_bugs_spaw):
		lv_bug = lv_bug_scene.instantiate()
		$Bug_Spaw_Poin.add_child(lv_bug)
		lv_bug.transform.origin.x = (float(lv_numb_bugs+1)/2)-2
		lv_bug.transform.origin.z = (float(lv_numb_bugs+1)/3)-2
		new_rand_numb()
		lv_bug.rotate_object_local(Vector3(0, 1, 0), -lv_random_turn)

	globalvariables.gv_roac_brow_spaw = lc_numb_bugs_spaw

func new_rand_numb():
	#lv_random_number_x = lv_rand_numb.randf_range(-1, 1)
	#lv_random_number_z = lv_rand_numb.randf_range(-1, 1)
	lv_random_turn = lv_rand_turn.randf_range(deg_to_rad(150),deg_to_rad(-150))


Hope this helps. :-)

thank you!