I want enemies to spawn in a specific location/s. My main server script handles a Heartbeat game loop which looks for ready players, loads them on randomly selected map, etc.
My question is: How should I integrate the enemy spawning function within that main script, so it doesn't interrupt anything and doesn't yield until the spawning loop is done under certain condition (like "game over")?
Here is a bit of the main script:
Services.RunService.Heartbeat:Connect(function()
if GameStatus.Intermission == true or GameStatus.inProgress == true then return end
GameStatus.Intermission = true
print('Intermission...')
repeat -- Don't start the game until enough Players pressed 'Ready'
if Counts:GetAttribute('isReadyCount') < GameSettings.PlayersNeeded then
warn('Not enough players to start the game')
end
task.wait(1)
until Counts:GetAttribute('isReadyCount') >= GameSettings.PlayersNeeded
print('Enough players...')
task.wait(3)
GameStatus.inProgress = true
GameStatus.Intermission = false
print('Game is starting, Intermission ended...')
-- Random map is being chosen
local Maps = (Services.ServerStorage.Maps):GetChildren()
local RandomMap = Maps[math.random(1, #Maps)]
local ClonedMap = RandomMap:Clone()
ClonedMap.Parent = game.Workspace
-- Send ready Players to the game
local iCount = 0
for i, Player in Services.Players:GetPlayers() do
if Player == isReadyList[Player.UserId] then
PlayingList[Player.UserId] = Player
iCount += 1
Player.Character:PivotTo(SpawnOrigin.CFrame)
local Sword = (Weapons.Melee.ClassicSword):Clone()
Sword.Parent = Player.Backpack
Services.ReplicatedStorage.Events.Server.ChangeCamera:FireClient(Player)
end
end
Counts:SetAttribute('PlayingCount', iCount)
end)
My main idea was to use task.spawn() or coroutine with function written like shown below, but wouldn’t that just loop forever, even when I coroutine.yield it? If I decide to break the loop, wouldn’t that mean I can’t use that loop anymore because its broken?
function spawnEnemies()
local Enemies = Services.ReplicatedStorage.Enemies:GetChildren()
while true do
local randomEnemy = Enemies[math.random(1, #Enemies)]:Clone()
randomEnemy.Parent = game.Workspace
randomEnemy:PivotTo(EnemySpawnOrigin.CFrame)
task.wait(1)
end
end
local Spawns = workspace.Debris --Put this variable into what ur MAP's Folder of enemy spawns parts
local EnemyAmount = 10
local Enemy = workspace.Debris --put this to what ur enemy model actually is
for i = 1, EnemyAmount do
local Cloned = Enemy:Clone()
Cloned:PivotTo(Spawns:GetChildren()[math.random(1, #Spawns:GetChildren())])
Cloned.Parent = workspace.Debris --Put this to where u want ur enemy to be parented at
end
this may not work exactly with ur script, but this should be enough to give u idea
Thats good and all, but how would I call that function inside my main? I just call it when the game starts and listen to when the game ends - if so, break the loop? I suppose its not recommended to coroutine.create(function()) each time.
if i understand correctly, ure afraid of breaking the loop thinking it will never work again, but calling the function u made will cause it to loop again
function spawnEnemies()
local Enemies = Services.ReplicatedStorage.Enemies:GetChildren()
while true do
local randomEnemy = Enemies[math.random(1, #Enemies)]:Clone()
randomEnemy.Parent = game.Workspace
randomEnemy:PivotTo(EnemySpawnOrigin.CFrame)
task.wait(1)
end
end
spawnEnemies() -- type this whenever u wanna loop again
The script I’ve sent in the post is cropped. After loading players there is a bunch of other stuff, like waiting for all players to die, waiting if game ends somehow, etc. If I want to add a while loop to script, my code below won’t run unless the loop was broken, so checking for certain conditions won’t happen because of this. My problem lies more on a how do I run my loop simultaneously without interrupting my main script rather than how do I spawn enemies.
Hope that makes sense…
OOh i think i get now, what u want is for the function to run independently so that i wont stop ur main function from running through? if thats the case, use this
function spawnEnemies()
local Enemies = Services.ReplicatedStorage.Enemies:GetChildren()
while true do
local randomEnemy = Enemies[math.random(1, #Enemies)]:Clone()
randomEnemy.Parent = game.Workspace
randomEnemy:PivotTo(EnemySpawnOrigin.CFrame)
task.wait(1)
end
end
task.spawn(spawnEnemies)
--other stuff
the other stuff will still continue while the spawnenemies also running , meaning there will be multiple running functions without stopping anything
So task.spawn() will be fine? And just basicly, if I want to break it, I can call the function again without any problems?
function spawnEnemies()
local stopSpawning = false
local Enemies = Services.ReplicatedStorage.Enemies:GetChildren()
while true do
if stopSpawning then break end
local randomEnemy = Enemies[math.random(1, #Enemies)]:Clone()
randomEnemy.Parent = game.Workspace
randomEnemy:PivotTo(EnemySpawnOrigin.CFrame)
task.wait(1)
end
end
task.spawn(spawnEnemies)
This would break the loop if stopSpawning is set to true?
yea, break it whenever u want, and call it again using task.spawn(spawnEnemies) , its like u are walking on one road, then theres 2 roads, u cloned urself so both u and ur clone can go each of the road, idk if i explained it well
yea, but i recommend putting the local stopSpawning = false way above outside the function, so u can just do
local stopSpawning = false
function spawnEnemies()
stopSpawning = false
local Enemies = Services.ReplicatedStorage.Enemies:GetChildren()
while true do
if stopSpawning == true then break end
local randomEnemy = Enemies[math.random(1, #Enemies)]:Clone()
randomEnemy.Parent = game.Workspace
randomEnemy:PivotTo(EnemySpawnOrigin.CFrame)
task.wait(1)
end
end
task.spawn(spawnEnemies)
task.wait(5) -- example
stopSpawning = true
Thank you very much! Last question about the task library… the task.spawn() will just end when the code inside passed function finishes? Asking, because I don’t want anything running in the background unnecessarily.
yes it will just end, it wont go the main function, its like a seperate script, it works on its own and even if it causes an error, it wont affect the main function u been running task.spawn() is just a branch not the body of the tree