Help with script for spawning 2 enemies at once?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to make it so the Dogs and Zombies spawn together rather than waiting on the dogs to finish spawning then allowing zombies to spawn

  2. What is the issue? Include screenshots / videos if possible!
    Dogs will spawn in first and once they’ve reached their onscreen limit the zombies begin to spawn in.

local CS = game:getService("CollectionService")

function IsActivated (spawner, Range)  

	local Activated = false

	for _,Player in game.Players:GetChildren() do

		local Character = Player.Character

		if Character and Character.PrimaryPart ~= nil then

			if (Character.PrimaryPart.Position-spawner.Position).Magnitude < Range then

				Activated = true
				break

			end

		end

	end

	return Activated

end

while true do

	wait(script.SpawnSpeed.Value)

	if game.ReplicatedStorage.Values.zombiesRemaining.Value > 0  and game.ReplicatedStorage.Values.zombiesOnScreen.Value < game.ReplicatedStorage.Values.zombieLimit.Value then
		if game.ReplicatedStorage.Values.gameInProgress.Value == true then
			if game.ReplicatedStorage.Values.DogZomRound.Value == true then
				
				local Spawns = game.Workspace.DogSpawns:GetChildren()
				local Spawns2 = game.Workspace.ZomSpawn:GetChildren()
				local SpawnRange = 250

				for i, doggiespawn in Spawns do
					if game.ReplicatedStorage.Values.gameInProgress.Value == true and game.ReplicatedStorage.Values.zombiesRemaining.Value > 0  and game.ReplicatedStorage.Values.zombiesOnScreen.Value < game.ReplicatedStorage.Values.zombieLimit.Value then
						if game.ReplicatedStorage.Values.DogsOnScreen.Value < game.ReplicatedStorage.Values.dogLimit.Value then
							
										local table = {
											game.Workspace.DogSpawns.Part1,
											game.Workspace.DogSpawns.Part2,
											game.Workspace.DogSpawns.Part3,
											game.Workspace.DogSpawns.Part4,
											game.Workspace.DogSpawns.Part5,
											game.Workspace.DogSpawns.Part6,
											game.Workspace.DogSpawns.Part7,

										}

										local random2 = math.random(1,5)

										for i, v in ipairs(table) do

											local random = math.random(1,7)
											local doggiespawn = table[random] 
								if game.ReplicatedStorage.Values.gameInProgress.Value == true and game.ReplicatedStorage.Values.zombiesRemaining.Value > 0  and game.ReplicatedStorage.Values.zombiesOnScreen.Value < game.ReplicatedStorage.Values.zombieLimit.Value then
									if game.ReplicatedStorage.Values.DogsOnScreen.Value < game.ReplicatedStorage.Values.dogLimit.Value then
													doggiespawn.Loop:Play()
													doggiespawn.Glow.Enabled = true
													doggiespawn.ParticleEmitter.Enabled = true
													wait(1.4)
													v.Souls.Enabled = true
													doggiespawn.Lightning:Play()
													wait(0.4)
													doggiespawn.Glow.Enabled = false
													doggiespawn.ParticleEmitter.Enabled = false
													doggiespawn.Union.Transparency = 0
													wait(0.2)
													doggiespawn.Union.Transparency = 1
													local NPC3 = game.ReplicatedStorage.DogsLateRound.Zombie:Clone()
													NPC3.Parent = doggiespawn.Parent
													NPC3.HumanoidRootPart.CFrame =  doggiespawn.CFrame + Vector3.new(0, 2, 0)
													CS:AddTag(NPC3, "Zombie")
										game.ReplicatedStorage.Values.zombiesRemaining.Value = game.ReplicatedStorage.Values.zombiesRemaining.Value - 1	
										game.ReplicatedStorage.Values.DogsOnScreen.Value = game.ReplicatedStorage.Values.DogsOnScreen.Value + 1
												end
											end
							end
						end
					end
					end

				for i, ZomSpawn in Spawns2 do
					if game.ReplicatedStorage.Values.gameInProgress.Value == true and game.ReplicatedStorage.Values.zombiesRemaining.Value > 0  and game.ReplicatedStorage.Values.zombiesOnScreen.Value < game.ReplicatedStorage.Values.zombieLimit.Value then

						if IsActivated(ZomSpawn,SpawnRange) then

							local ZomSpawn = ZomSpawn
							local sound1 = ZomSpawn:WaitForChild("sound1")
							local sound2 = ZomSpawn:WaitForChild("sound2")
							local sounds = {sound1, sound2} 
							sounds[math.random(1, #sounds)]:Play()
							ZomSpawn.D1.Enabled = true
							ZomSpawn.D2.Enabled = true
							wait(0.5)
							ZomSpawn.D1.Enabled = false
							ZomSpawn.D2.Enabled = false
							local NPC = game.ServerStorage.Zombie:Clone()

							NPC.Parent = game.Workspace.Zombies
							NPC.HumanoidRootPart.CFrame = 	ZomSpawn.CFrame + Vector3.new(0, 2.5, 0)
							NPC.HumanoidRootPart.Anchored = true
							CS:AddTag(NPC, "Zombie")
							game.ReplicatedStorage.Values.zombiesRemaining.Value = game.ReplicatedStorage.Values.zombiesRemaining.Value - 1	

						end
					end
				end
				
			else

--rest of code handles single dog rounds/boss rounds/regular rounds
 

so im wanting to make it so while the dogs are spawning the zombies are spawning too, im just not sure how to handle limiting the dogs on screen with zombies in a single function. i have them seperated due to how they spawn and to limit the amount of dogs on screen as well as zombies on screen

1 Like

task.spawn(<function>) will run the given function without yielding. Implement it to the part with yields.

2 Likes

so this is in the right direction! ironically its spawning a bunch of dogs/Zombies at a time, so its close i just need to limit it. i added task.spawn after “for i, doggiespawn in Spawns do”. should i try placing it after the

					if game.ReplicatedStorage.Values.gameInProgress.Value == true and game.ReplicatedStorage.Values.zombiesRemaining.Value > 0  and game.ReplicatedStorage.Values.zombiesOnScreen.Value < game.ReplicatedStorage.Values.zombieLimit.Value then
						if game.ReplicatedStorage.Values.DogsOnScreen.Value < game.ReplicatedStorage.Values.dogLimit.Value then

?

You should spawn functions such as visual effects, in you case it is

													doggiespawn.Loop:Play()
													doggiespawn.Glow.Enabled = true
													doggiespawn.ParticleEmitter.Enabled = true
													wait(1.4)
													v.Souls.Enabled = true
													doggiespawn.Lightning:Play()
													wait(0.4)
													doggiespawn.Glow.Enabled = false
													doggiespawn.ParticleEmitter.Enabled = false
													doggiespawn.Union.Transparency = 0
													wait(0.2)
													doggiespawn.Union.Transparency = 1
													local NPC3 = game.ReplicatedStorage.DogsLateRound.Zombie:Clone()
													NPC3.Parent = doggiespawn.Parent
													NPC3.HumanoidRootPart.CFrame =  doggiespawn.CFrame + Vector3.new(0, 2, 0)
													CS:AddTag(NPC3, "Zombie")```

OH so the task.spawn would handle the visual/sfx ? let me try that

so this does work, i just added a task.spawn to the dogs and the zombies and dogs spawn in together, but it’ll spawn in all of the dogs at the same time rather than cycling thru each spawning point.

Use task.spawn to spawn it on a different thread.

Fixed script:

--//Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CS = game:getService("CollectionService")

--//Functions
local function IsActivated(spawner, Range)  
	local Activated = false
	
	for _, Player in ipairs(Players:GetPlayers()) do
		local Character = Player.Character

		if Character and Character.PrimaryPart then
			if (Character.PrimaryPart.Position - spawner.Position).Magnitude < Range then
				Activated = true
				
				break
			end
		end
	end

	return Activated
end

while task.wait(script.SpawnSpeed.Value) do
	if ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
		if ReplicatedStorage.Values.gameInProgress.Value then
			if ReplicatedStorage.Values.DogZomRound.Value then
				local Spawns = workspace.DogSpawns:GetChildren()
				local Spawns2 = workspace.ZomSpawn:GetChildren()
				local SpawnRange = 250
				
				task.spawn(function()
					for i, doggiespawn in Spawns do
						if ReplicatedStorage.Values.gameInProgress.Value == true and ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
							if ReplicatedStorage.Values.DogsOnScreen.Value < ReplicatedStorage.Values.dogLimit.Value then
								local table = {
									workspace.DogSpawns.Part1,
									workspace.DogSpawns.Part2,
									workspace.DogSpawns.Part3,
									workspace.DogSpawns.Part4,
									workspace.DogSpawns.Part5,
									workspace.DogSpawns.Part6,
									workspace.DogSpawns.Part7,

								}

								local random2 = math.random(1, 5)

								for i, v in ipairs(table) do
									local random = math.random(1,7)
									local doggiespawn = table[random] 

									if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
										if ReplicatedStorage.Values.DogsOnScreen.Value >= ReplicatedStorage.Values.dogLimit.Value then
											continue
										end

										doggiespawn.Loop:Play()
										doggiespawn.Glow.Enabled = true
										doggiespawn.ParticleEmitter.Enabled = true

										task.wait(1.4)
										v.Souls.Enabled = true
										doggiespawn.Lightning:Play()

										task.wait(0.4)
										doggiespawn.Glow.Enabled = false
										doggiespawn.ParticleEmitter.Enabled = false
										doggiespawn.Union.Transparency = 0

										task.wait(0.2)
										doggiespawn.Union.Transparency = 1

										local NPC3 = ReplicatedStorage.DogsLateRound.Zombie:Clone()
										NPC3.Parent = doggiespawn.Parent
										NPC3.HumanoidRootPart.CFrame =  doggiespawn.CFrame + Vector3.new(0, 2, 0)

										CS:AddTag(NPC3, "Zombie")
										ReplicatedStorage.Values.zombiesRemaining.Value -= 1	
										ReplicatedStorage.Values.DogsOnScreen.Value += 1
									end
								end
							end
						end
					end
				end)
				
				for i, ZomSpawn in Spawns2 do
					if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
						if IsActivated(ZomSpawn, SpawnRange) then
							local ZomSpawn = ZomSpawn
							local sound1 = ZomSpawn:WaitForChild("sound1")
							local sound2 = ZomSpawn:WaitForChild("sound2")
							local sounds = {sound1, sound2} 
							sounds[math.random(1, #sounds)]:Play()
							ZomSpawn.D1.Enabled = true
							ZomSpawn.D2.Enabled = true
							
							task.wait(0.5)
							ZomSpawn.D1.Enabled = false
							ZomSpawn.D2.Enabled = false
							
							local NPC = ServerStorage.Zombie:Clone()
							NPC.HumanoidRootPart.CFrame = ZomSpawn.CFrame + Vector3.new(0, 2.5, 0)
							NPC.HumanoidRootPart.Anchored = true
							NPC.Parent = workspace.Zombies

							CS:AddTag(NPC, "Zombie")
							ReplicatedStorage.Values.zombiesRemaining.Value -= 1
						end
					end
				end

			else
--rest of code handles single dog rounds/boss rounds/regular rounds

I would also suggest learning about guard clauses to prevent this much clutter.

(make sure to use continue for guard clauses that are in loop)

so this almost works, for some reason they spawn an extra zombie or dog. the zombiereamining value will get to -1 instead of stopping at 0

Apologizes for the late reply, this is what i tried

--//Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CS = game:getService("CollectionService")

--//Functions
local function IsActivated(spawner, Range)  
	local Activated = false

	for _, Player in ipairs(Players:GetPlayers()) do
		local Character = Player.Character

		if Character and Character.PrimaryPart then
			if (Character.PrimaryPart.Position - spawner.Position).Magnitude < Range then
				Activated = true

				break
			end
		end
	end

	return Activated
end

while task.wait(script.SpawnSpeed.Value) do
	if ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
		if ReplicatedStorage.Values.gameInProgress.Value then
			if ReplicatedStorage.Values.DogZomRound.Value then
				local Spawns = workspace.DogSpawns:GetChildren()
				local Spawns2 = workspace.ZomSpawn:GetChildren()
				local SpawnRange = 250

				task.spawn(function()
					for i, doggiespawn in Spawns do
						if ReplicatedStorage.Values.gameInProgress.Value == true and ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
							if ReplicatedStorage.Values.DogsOnScreen.Value < ReplicatedStorage.Values.dogLimit.Value then
								local table = {
									workspace.DogSpawns.Part1,
									workspace.DogSpawns.Part2,
									workspace.DogSpawns.Part3,
									workspace.DogSpawns.Part4,
									workspace.DogSpawns.Part5,
									workspace.DogSpawns.Part6,
									workspace.DogSpawns.Part7,

								}

								local random2 = math.random(1, 5)

								for i, v in ipairs(table) do
									local random = math.random(1,7)
									local doggiespawn = table[random] 

									if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
										if ReplicatedStorage.Values.DogsOnScreen.Value >= ReplicatedStorage.Values.dogLimit.Value then
											continue
										end

										doggiespawn.Loop:Play()
										doggiespawn.Glow.Enabled = true
										doggiespawn.ParticleEmitter.Enabled = true

										task.wait(1.4)
										v.Souls.Enabled = true
										doggiespawn.Lightning:Play()

										task.wait(0.4)
										doggiespawn.Glow.Enabled = false
										doggiespawn.ParticleEmitter.Enabled = false
										doggiespawn.Union.Transparency = 0

										task.wait(0.2)
										doggiespawn.Union.Transparency = 1

										local NPC3 = ReplicatedStorage.DogsLateRound.Zombie:Clone()
										NPC3.Parent = doggiespawn.Parent
										NPC3.HumanoidRootPart.CFrame =  doggiespawn.CFrame + Vector3.new(0, 2, 0)

										CS:AddTag(NPC3, "Zombie")
										ReplicatedStorage.Values.zombiesRemaining.Value -= 1	
										ReplicatedStorage.Values.DogsOnScreen.Value += 1
									end
								end
							end
						end
					end
	print "dog task end"
				end)
				if ReplicatedStorage.Values.zombiesRemaining.Value == 0 then
					print "no spawn pls"
				else
					
				
				for i, ZomSpawn in Spawns2 do
					if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0  and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
						if IsActivated(ZomSpawn, SpawnRange) then
							local ZomSpawn = ZomSpawn
							local sound1 = ZomSpawn:WaitForChild("sound1")
							local sound2 = ZomSpawn:WaitForChild("sound2")
							local sounds = {sound1, sound2} 
							sounds[math.random(1, #sounds)]:Play()
							ZomSpawn.D1.Enabled = true
							ZomSpawn.D2.Enabled = true

							task.wait(0.5)
							ZomSpawn.D1.Enabled = false
							ZomSpawn.D2.Enabled = false

							local NPC = ServerStorage.Zombie:Clone()
							NPC.HumanoidRootPart.CFrame = ZomSpawn.CFrame + Vector3.new(0, 2.5, 0)
							NPC.HumanoidRootPart.Anchored = true
							NPC.Parent = workspace.Zombies

							CS:AddTag(NPC, "Zombie")
							ReplicatedStorage.Values.zombiesRemaining.Value -= 1
						end
					end
				end
end
else

---

i tried adding a if statement. earlier i tried changing the task.wait to 10.5 and the remaining value will still be 0. i did notice when it reached it would print “dog task end” but then would spawn another zombie. thats why i added that if statement but it still didnt work. i also tried flipping around the spawing (so zombie line would come first then dogs) but that didnt work, only zombies would spawn. i tried adding a task.spawn to the zombie line but then it went back to spawning in a lot of dogs + zombies. Any suggestions?

You can just use math.max to make sure it never goes below 0.

Fixed script:

--//Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CS = game:getService("CollectionService")

--//Functions
local function IsActivated(spawner, Range)  
	local Activated = false

	for _, Player in ipairs(Players:GetPlayers()) do
		local Character = Player.Character
		local PrimaryPart = Character and Character.PrimaryPart
		
		if not PrimaryPart then
			continue
		end

		if (PrimaryPart.Position - spawner.Position).Magnitude < Range then
			Activated = true

			break
		end
	end

	return Activated
end

while task.wait(script.SpawnSpeed.Value) do
	if ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
		if ReplicatedStorage.Values.gameInProgress.Value then
			if ReplicatedStorage.Values.DogZomRound.Value then
				local Spawns = workspace.DogSpawns:GetChildren()
				local Spawns2 = workspace.ZomSpawn:GetChildren()
				local SpawnRange = 250

				task.spawn(function()
					for i, doggiespawn in Spawns do
						if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
							if ReplicatedStorage.Values.DogsOnScreen.Value < ReplicatedStorage.Values.dogLimit.Value then
								local table = {
									workspace.DogSpawns.Part1,
									workspace.DogSpawns.Part2,
									workspace.DogSpawns.Part3,
									workspace.DogSpawns.Part4,
									workspace.DogSpawns.Part5,
									workspace.DogSpawns.Part6,
									workspace.DogSpawns.Part7,
								}

								for i, v in ipairs(table) do
									local random = math.random(1, 7)
									local doggiespawn = table[random] 

									if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
										if ReplicatedStorage.Values.DogsOnScreen.Value >= ReplicatedStorage.Values.dogLimit.Value then
											continue
										end

										doggiespawn.Loop:Play()
										doggiespawn.Glow.Enabled = true
										doggiespawn.ParticleEmitter.Enabled = true

										task.wait(1.4)
										v.Souls.Enabled = true
										doggiespawn.Lightning:Play()

										task.wait(0.4)
										doggiespawn.Glow.Enabled = false
										doggiespawn.ParticleEmitter.Enabled = false
										doggiespawn.Union.Transparency = 0

										task.wait(0.2)
										doggiespawn.Union.Transparency = 1

										local NPC3 = ReplicatedStorage.DogsLateRound.Zombie:Clone()
										NPC3.HumanoidRootPart.CFrame =  doggiespawn.CFrame + Vector3.yAxis * 2
										NPC3.Parent = doggiespawn.Parent

										CS:AddTag(NPC3, "Zombie")
										ReplicatedStorage.Values.zombiesRemaining.Value = math.max(ReplicatedStorage.Values.zombiesRemaining.Value - 1, 0)
										ReplicatedStorage.Values.DogsOnScreen.Value += 1
									end
								end
							end
						end
					end
				end)

				for i, ZomSpawn in Spawns2 do
					if ReplicatedStorage.Values.gameInProgress.Value and ReplicatedStorage.Values.zombiesRemaining.Value > 0 and ReplicatedStorage.Values.zombiesOnScreen.Value < ReplicatedStorage.Values.zombieLimit.Value then
						if IsActivated(ZomSpawn, SpawnRange) then
							local sound1 = ZomSpawn:WaitForChild("sound1")
							local sound2 = ZomSpawn:WaitForChild("sound2")
							local sounds = {sound1, sound2} 
							sounds[math.random(1, #sounds)]:Play()
							ZomSpawn.D1.Enabled = true
							ZomSpawn.D2.Enabled = true

							task.wait(0.5)
							ZomSpawn.D1.Enabled = false
							ZomSpawn.D2.Enabled = false

							local NPC = ServerStorage.Zombie:Clone()
							NPC.HumanoidRootPart.CFrame = ZomSpawn.CFrame + Vector3.yAxis * 2.5
							NPC.HumanoidRootPart.Anchored = true
							NPC.Parent = workspace.Zombies

							CS:AddTag(NPC, "Zombie")
							ReplicatedStorage.Values.zombiesRemaining.Value = math.max(ReplicatedStorage.Values.zombiesRemaining.Value - 1, 0)
						end
					end
				end

			else
				--rest of code handles single dog rounds/boss rounds/regular rounds

Sorry again for the late reply, havent had a chance to get into studio.

I tried this script, and im still getting to -1 for the zombie remaining values.

i tried making a few changes to the script but it either would spam spawn the dogs or not spawn the dogs at all. im not sure if its spawning too many dogs or zombies for it to break the script.

You have a function you didn’t include that subtracts from the zombieRemaining value then.