My zombie spawning function wont work

You can write your topic however you want, but you need to answer these questions:
What I want to achieve
I would like my round system to spawn and teleport the zombies to the spawn locations which are inside of each map.

  1. The issue:
  1. It only spawns 1 zombie.
  2. It errors when I try to fire the function again.
  1. What I have tried:
    I have look on YouTube and the dev hub and found nothing to help me, I have been debugging for the last couple of hours and cant find the problem.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local ZombieSpawnPointsFolder = Map:WaitForChild("ZombieSpawnPoints")
local ZombiesSpawns = ZombieSpawnPointsFolder:GetChildren()

local Difficultys = ReplicatedStorage:WaitForChild("Difficultys"):GetChildren()

local Difficulty = Difficultys[math.random(1, #Difficultys)]

local maxnumber = ReplicatedStorage:WaitForChild("MaxNumber")
local NewWaveEvent = ReplicatedStorage:WaitForChild("NewWave")
local WaveSystem = ReplicatedStorage:WaitForChild("WaveSystem")
local WaveNumber = WaveSystem:WaitForChild("TotalNumberOfWaves")

function NewWave() -- This is the function that errors --

    if Difficulty.Value == 1 then
        maxnumber.Value = 70
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 2 then
        maxnumber.Value = 80
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 3 then
        maxnumber.Value = 90
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 4 then
        maxnumber.Value = 100
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 5 then
        maxnumber.Value = 110
        print("Zombies spawning: "..maxnumber.Value)
	end
	
	
	
    repeat 
        local spawnLocation = ZombiesSpawns[math.random(1, #ZombiesSpawns)]
        local Zombie = Zombies[math.random(1, #Zombies)]
        local TpTo = CFrame.new(spawnLocation.Position)

        local new = Zombie:Clone()
        new.Parent = ZombieCloningFolder
        new:SetPrimaryPartCFrame(TpTo.CFrame)        

        maxnumber.Value = maxnumber.Value - 1

	until maxnumber.Value == 1

end
NewWave()

NewWaveEvent.OnServerEvent:Connect(function()
    NewWave()
    print("Started wave number: "..WaveNumber.Value)
end)

if maxnumber.Value <= 0 then
    print("Wave cloning succesful...")
end

This is only the erroring part of the code as I wish not to share the whole 300 lines.

Thanks! apoaddda

2 Likes

Can you please tell me what does the error shows?

1 Like

So these are my errors:
Screenshot (264)
All of the line numbers are included in my code above.

2 Likes

well you’ve already stored cframe value so you dont need to add .CFrame after TpTo.

try this
new:SetPrimaryPartCFrame(TpTo)

This gets rid of the errors in the output, but it still only clones 1 zombie, do you know how to fix this?

2 Likes

hmmm… can you try adding wait() in your repeat function?

It now spawns 4 zombies, is there a way to spawn more also thank you for all your help.

2 Likes

Hm so can you try changing repeat function with while loop?

heres the example

   while wait() do
            if (maxnumber.Value <= 1) then
                return
            else
                local spawnLocation = ZombiesSpawns[math.random(1, #ZombiesSpawns)]
                local Zombie = Zombies[math.random(1, #Zombies)]
                local TpTo = CFrame.new(spawnLocation.Position)

            local new = Zombie:Clone()
            new.Parent = ZombieCloningFolder
            new:SetPrimaryPartCFrame(TpTo.CFrame)        

            maxnumber.Value = maxnumber.Value - 1local spawnLocation = ZombiesSpawns[math.random(1, #ZombiesSpawns)]
            local Zombie = Zombies[math.random(1, #Zombies)]
            local TpTo = CFrame.new(spawnLocation.Position)

            local new = Zombie:Clone()
            new.Parent = ZombieCloningFolder
            new:SetPrimaryPartCFrame(TpTo.CFrame)        

            maxnumber.Value = maxnumber.Value - 1
        end
    end
2 Likes

I dont know if the fact I now have two while loops is causing a problem, here is most of my code:

-- Date created: 27/03/2021 --
-- Last updated: 2/03/2021 at 10:30--

-- Services --
local ServerStorage = game:GetService("ServerStorage") -- Gets server storage service --
local ReplicatedStorage = game:GetService("ReplicatedStorage") -- Gets replicated storage service --
local WorkSpace = game:GetService("Workspace") -- Gets workspace service --

-- Map varibles --
local MapsFolder = ServerStorage:WaitForChild("Maps") -- Finds the map folder --
local Maps = MapsFolder:GetChildren() -- Get the maps in the folder --
local CloneFolder = WorkSpace:WaitForChild("Map") -- The folder that the map will be cloned into --

-- Teleport Varibles 
local RoundFolder = WorkSpace:WaitForChild("RoundSystem") -- Folder containing tp part --
local TpBrick = RoundFolder:WaitForChild("LobbyTeleport") -- tp part

-- Replicated Storage Varibles --
local MapSystem = ReplicatedStorage:WaitForChild("MapSystem") -- Gets the value holding folder --
local Creator = MapSystem:WaitForChild("CreatorUserName") -- Gets the creator username --
local RoundLength = MapSystem:WaitForChild("RoundLength") -- Gets the round length (Seconds) --
local IntermissionLength = MapSystem:WaitForChild("IntermissionLength") -- Gets the intermission length (Seconds) --
local SecondsLeft = MapSystem:WaitForChild("SecondsLeft") -- Gets the seconds left value --
local MinutesLeft = MapSystem:WaitForChild("MinutesLeft") -- Gets the minutes left value --
local RoundSystemFolder = ReplicatedStorage:WaitForChild("RoundSystem") -- Gets the round system holding folder --
local ClientTeleportEvent = RoundSystemFolder:WaitForChild("ClientGuiTeleport") -- Gets the client teleport remote event --
local ChosenMap = MapSystem:WaitForChild("ChosenMap") -- Gets the choosen map string --
local TimerTag = MapSystem:WaitForChild("TimeLeftTag") -- Gets the timer display string --
local ClientToServer = RoundSystemFolder:WaitForChild("ServerToClient") -- Gets the server to client event --
local ClientEventFolder = ReplicatedStorage:WaitForChild("CharacterEvents") -- Gets the character events folder --
local ResetEvent = ClientEventFolder:WaitForChild("ResetStatEvent") -- Resets stats event --

local Map -- Change this in the script later --

function NewMap() -- This function will run when a round is over --
    -- Clears the old map --
    CloneFolder:ClearAllChildren()

    -- Map choosing --
    Map = Maps[math.random(1, #Maps)]
    
    -- Clones the map --
    Map:Clone().Parent = CloneFolder

    -- Sets the game items to the desired settings --
    if Map:FindFirstChild("Settings") then -- Finds the setting information --
		game.Lighting.Atmosphere.Density = Map.Settings.FogDensity.Value -- Sets fog density to that maps settings --
		game.Lighting.Atmosphere.Color = Map.Settings.FogMain.Value -- Sets atmosphere colour to that maps settings--
		game.Lighting.Atmosphere.Decay = Map.Settings.FogDecay.Value -- Sets fog decay value to that maps settings --
		game.Lighting.TimeOfDay = Map.Settings.Time.Value -- Sets the time of day to that maps settings --
	end

    -- Map creator --
    local mapcreator 
	mapcreator = Map:FindFirstChild("Creator")
	
	if Map:FindFirstChild("Creator") then -- Finds then value "Creator" which is in each map --
		Creator.Value = tostring(mapcreator.Value) -- Sets the value to the creator of the map --
	end
    
    ChosenMap.Value = tostring(Map.Name) -- Sets the value to map name --

    --[[ 
    End of the function.    
    --]]
end

game.Players.PlayerAdded:Connect(function(player)
    
    local StatsFolder = Instance.new("Folder")
    StatsFolder.Parent = player
    StatsFolder.Name = "IsInWave"

    local InWave = Instance.new("BoolValue")
    InWave.Name = "InWave"
    InWave.Parent = player
    InWave.Value = false
    
end)

local player = game.Players.LocalPlayer -- Gets the local player --

ClientToServer.OnServerEvent:Connect(function() -- Will run when client to server event fired --
    if Map:FindFirstChild("MapTeleportLocation") then -- Finds the map teleport location --
        local TpValue = TpBrick:WaitForChild("TeleportValue") -- Finds the vector 3 value in the teleport part in workspace --
        local TeleportTo = Map:WaitForChild("MapTeleportLocation") -- Finds the part to teleport to --
        TpValue.Value = TeleportTo.Position -- Sets the value to the position of the part --
        print("Teleport success") -- Prints teleport success to let the player know that it was successful --
        player.IsInWave.InWave = true -- Changes the value to let the script know the player is in the wave --
    end --[[
        End of the if statment --
        --]]
    wait(15) -- Waits 15 seconds so the function doesnt run again and cause confussion --
end) --[[
    End of the remote event function --
    --]]

NewMap() -- When the first user joins the server this function will fire --

-- Wave system: --
-- Server Storage varibles --
local ZombieFolder = ServerStorage:WaitForChild("Zombies") -- Finds the folder containing the zombies in it --
local Zombies = ZombieFolder:GetChildren() -- Gets the zombie models from the folder --

local ZombieCloningFolder = WorkSpace:WaitForChild("WaveSystem") -- Get the cloning folder in workspace --

local RoundOverServerEvent = MapSystem:WaitForChild("ServerToClientRoundOverEvent") -- Gets the remote event telling the script if the round is over --

RoundOverServerEvent.OnServerEvent:Connect(function() -- If this event is fired then this code runs --
    ZombieCloningFolder:ClearAllChildren() -- Clears all of the zombies --
    print("Failed to finish all 9 rounds...") -- Prints that the players failed to complete the 9 rounds --
    print("Try again next time...") -- Prints try again next time --
    wait(10) -- Waits 10 seconds so that there wont be more remote events --
end) --[[
    End of the the round over function
    --]]
local ZombieSpawnPointsFolder = Map:WaitForChild("ZombieSpawnPoints")
local ZombiesSpawns = ZombieSpawnPointsFolder:GetChildren()

local Difficultys = ReplicatedStorage:WaitForChild("Difficultys"):GetChildren()

local Difficulty = Difficultys[math.random(1, #Difficultys)]

local maxnumber = ReplicatedStorage:WaitForChild("MaxNumber")
local NewWaveEvent = ReplicatedStorage:WaitForChild("NewWave")
local WaveSystem = ReplicatedStorage:WaitForChild("WaveSystem")
local WaveNumber = WaveSystem:WaitForChild("TotalNumberOfWaves")

function NewWave() -- This is the function that errors --

    if Difficulty.Value == 1 then
        maxnumber.Value = 70
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 2 then
        maxnumber.Value = 80
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 3 then
        maxnumber.Value = 90
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 4 then
        maxnumber.Value = 100
        print("Zombies spawning: "..maxnumber.Value)
    elseif Difficulty.Value == 5 then
        maxnumber.Value = 110
        print("Zombies spawning: "..maxnumber.Value)
	end
	
	
	
	while wait() do
		if (maxnumber.Value <= 1) then
			return
		else        
			maxnumber.Value = maxnumber.Value - 1
			local spawnLocation = ZombiesSpawns[math.random(1, #ZombiesSpawns)]
			local Zombie = Zombies[math.random(1, #Zombies)]
			local TpTo = CFrame.new(spawnLocation.Position)

			local new = Zombie:Clone()
			new.Parent = ZombieCloningFolder
			new:SetPrimaryPartCFrame(TpTo)        

			maxnumber.Value = maxnumber.Value - 1
		end
	end

end
NewWave()

NewWaveEvent.OnServerEvent:Connect(function()
    NewWave()
    print("Started wave number: "..WaveNumber.Value)
end)

if maxnumber.Value <= 0 then
    print("Wave cloning succesful...")
end

while true do -- Will repeat forever --
   
    -- The function changing the timers display --
    if SecondsLeft.Value <= 9 then -- Finds out if the are less then 9 seconds left --
        TimerTag.Value = tostring(MinutesLeft.Value)..":0"..tostring(SecondsLeft.Value) -- Changes the timer accordingly -- 
    else -- Else statment
        TimerTag.Value = tostring(MinutesLeft.Value)..":"..tostring(SecondsLeft.Value) -- Changes the timer accordingly --
    end --[[
        End of the if statment 
        --]]

    if SecondsLeft.Value <= 0 then -- Finds out if there are no seconds left --
        MinutesLeft.Value = MinutesLeft.Value - 1 -- Takes 1 away from the minutes left value --
        SecondsLeft.Value = 59 -- Changes the seconds left value --
    else -- Else Statment --
        SecondsLeft.Value = SecondsLeft.Value - 1 -- Removes 1 from the seconds value --
    end --[[
        End of the else statment
        --]]

    wait(1) -- Waits 1 so the function runs properly

    if MinutesLeft.Value == 0 and SecondsLeft.Value == 0 then
        local RoundOverEvent = MapSystem:WaitForChild("ClientToServerRoundOverEvent")
        RoundOverEvent:FireAllClients()
        wait(IntermissionLength) -- Waits the intermission length --
        NewMap() -- New map is fired --
        MinutesLeft.Value = 9 -- Sets the remaining value to 9 --
        SecondsLeft.Value = 59 -- Sets the seconds value to 59 --
        TimerTag.Value = tostring(MinutesLeft.Value..":"..tostring(SecondsLeft.Value)) -- Changes the timer tag to display correctly --
    end
end
3 Likes

I think the problem is with maxnumber value instance. Can you check the value while in game? (in studio)

1 Like

So the value changes successfully, but now i am also getting another set of errors in the output:

2 Likes

You’re trying to get a position of a script? What line is that erroring on?

What I am trying to do is get the position of the spawn point which is inside of the map and the 1 error occurs on this line:

3 Likes

well something is wrong, it tries to get the position of script instead of a part…

1 Like

Do you have a script in the folder for the ZombieSpawns?

No I don’t, I haven’t touched the maps as I am not a builder, but in the spawns folder there is no scripts.

2 Likes

to prevent the error you can do this instead.

local TpTo = nil
if spawnLocation:IsA("Part") or spawnLocation:IsA("SpawnLocation") then 
TpTo = CFrame.new(spawnLocation.Position)
end
1 Like

Yea that removed the errors, but the zombie doesn’t seem to teleport.

2 Likes

Maybe set the CFrame before parenting? Does your zombie have a PrimaryPart?

1 Like

Yes the zombies have a primary part this is what the zombie model looks like:


The primary part is the HumanoidRootPart

3 Likes