Too many enemy spawning

Godot Version

Godot v.4.5.1

Question

Hello
I am more on the new side of programming, and have been trying to make a game for a class project. I have some enemies that i need to spawn on the left side of the screen. While i have been able to make that work i now have a new problem.
I can switch menu to game scene with the “-” keybind, then i will be throwing a snowball using either “A” or “D” depending on the side the enemy spawn (Only left for now). However when i click “Space” i am supposed to change the snowball to another kind.
Here is the problem, when i click “space” more then 1 enemy spawn, making there be 1-3 more then needed enemies spawning on the screen. The game onces started automatically spaws 1 enemy, and keeps doing that, until i click “Space”

Code

The EnemyMovementManager Script

extends Node

var Character = []

func _ready():
	print("EnemyManager works")
	Spawn_Left()

func acknowledge_character(New_Character):
	Character.append(New_Character)
	New_Character.global_position = Vector2(165, -281)

func Spawn_Left():
	if Character.size() == 0:
		return 
	Character.shuffle()
	var Enemy = Character[0]
	Enemy.global_position = Vector2(14, 182)

func Manager_Enemy_Hit(HE):
	if HE and HE in Character:
		HE.global_position = Vector2(84, -124)
	if Character.size() == 0:
		return
	Character.shuffle()
	var New_Enemy = Character[0]
	New_Enemy.global_position = Vector2(14, 182)

First Snowball Script

extends CharacterBody2D
@export var id := 1
var Movement_Speed_N = 400
var Course = 1
var piss_N = true

#Start function, places snowballs out of screen
func _ready():
	global_position = Vector2(-5, -94)
	hide()
#Check if it is snowball 1 (normal)
func _physics_process(_delta):
	if SnowballSwitchManager.active_snowball != 1:
		hide()
		velocity = Vector2.ZERO
		global_position = Vector2(-5, -94)
		return
	else:
		show()
		
	#Sets snowball 1 to true if false, mainly to use after switching back
	if piss_N == false:
		piss_N = true
		velocity.x = Course * Movement_Speed_N
	
	#The throw function for the snowball	
	if Input.is_action_just_pressed("Left_Throw"):
		show()
		global_position = Vector2(210, 225)
		velocity.x = -Movement_Speed_N
		Course = -1
		piss_N = true
	elif Input.is_action_just_pressed("Right_Throw"):
		show()
		global_position = Vector2(210, 225)
		velocity.x = Movement_Speed_N
		Course = 1
		piss_N = true
	
	#Check if there is a hit, gives points and respawns the snowball, 
	#for it to be used again
	if piss_N == true:
		var EnemyHit = move_and_collide(velocity * _delta)
		if EnemyHit:
			var Hit = EnemyHit.get_collider()
			if Hit.is_in_group("Enemy_Kid"):
				#add 20 points
				EnemyMovementManager.Manager_Enemy_Hit(Hit)          
				_Respawn_Snowball1()                 
				return
			elif Hit.is_in_group("Enemy_Adult"):
				#remove 10 points
				EnemyMovementManager.Manager_Enemy_Hit(Hit)           
				_Respawn_Snowball1()                   
				return
			elif Hit.is_in_group("Enemy_Police"):
				#end game
				EnemyMovementManager.Manager_Enemy_Hit(Hit)           
				_Respawn_Snowball1()                     
				return
	#Changes snowball 1 (normal) to snowball 2 (piss) if "piss" is clicked
	if Input.is_action_just_pressed("Piss"):
		SnowballSwitchManager.active_snowball = 2
		piss_N = false

#The respawn function that makes the snowball able to use again
func _Respawn_Snowball1():
	hide()
	velocity = Vector2.ZERO
	global_position = Vector2(-5, -94)

Second Snowball Script

extends CharacterBody2D
@export var id := 1
var Movement_Speed_P = 400
var Course = 1
var piss_P = false
var PissTimer = -1
var PissActiveTime = 5

#Start function, places snowballs out of screen
func _ready():
	global_position = Vector2(-5, -94)
	hide()
#Check if it is snowball 2 (piss)
func _physics_process(_delta):
	if SnowballSwitchManager.active_snowball != 2:
		hide()
		velocity = Vector2.ZERO
		global_position = Vector2(-5, -94)
		return
	else:
		show()
		
	#Check if "piss" have been clicked, if yes start a countdown
	if Input.is_action_just_pressed("Piss"):
		piss_P = true
		_start_countdown(PissActiveTime)
		
	#Calling countdown function
	_countdown(_delta)
	
	#The throw function for the snowball
	if Input.is_action_just_pressed("Left_Throw"):
		show()
		global_position = Vector2(285, 237)
		velocity.x = -Movement_Speed_P
		Course = -1
		piss_P = false
	elif Input.is_action_just_pressed("Right_Throw"):
		show()
		global_position = Vector2(285, 237)
		velocity.x = Movement_Speed_P
		Course = 1
		piss_P = false
		
	#Moves the snowball the correct direction
	velocity.x = Course * Movement_Speed_P
	
	#Check if there is a hit, gives points and respawns the snowball, 
	#for it to be used again
	var EnemyHit = move_and_collide(velocity * _delta)
	if EnemyHit:
		var Hit = EnemyHit.get_collider()
		if Hit.is_in_group("Enemy_Kid"):
			#add 20 points
			EnemyMovementManager.Manager_Enemy_Hit(Hit)           
			_Respawn_Snowball2()                   
			return
		elif Hit.is_in_group("Enemy_Adult"):
			#remove 10 points
			EnemyMovementManager.Manager_Enemy_Hit(Hit)          
			_Respawn_Snowball2()                    
			return
		elif Hit.is_in_group("Enemy_Police"):
			#end game 
			EnemyMovementManager.Manager_Enemy_Hit(Hit)        
			_Respawn_Snowball2()                   
			return

#The start of countdown funtion
func _start_countdown(Time_Seconds):
	PissTimer = Time_Seconds
#The countdown function, that changes snowball back when times up
func _countdown(delta):
	if PissTimer > 0:
		PissTimer -= delta
	elif PissTimer <= 0 and PissTimer != -1:
		PissTimer = -1
		SnowballSwitchManager.active_snowball = 1
#The respawn function that makes the snowball able to use again
func _Respawn_Snowball2():
	hide()
	velocity = Vector2.ZERO
	global_position = Vector2(-5, -94)
	piss_P = false

What have you attached these scripts to? If I understand your code correctly, the only time an enemy is spawned to the left is when Spawn_Left() is called, and you call that in the _ready() function.

So if this script instantiates (spawns) an object that contains the script, you have created a loop. The _ready() is called by each new object as it enters the scene tree, so Spawn_Left() is called with it.

Quickest way to fix this would be to move this code to an autoload (global script) so the _ready() runs once when the game starts, and won’t be affected by ingame events. Then you can also call the Spawn_Left() function from other scripts using GlobalScriptName.Spawn_Left() if you need to.

I’d offer other solutions, but I need to get some sleep. If you have further questions, there;s lots of people here who can answer them, and I’ll be sure to come back here when I wake up <3