Vizikk
Vizikk

Reputation: 1

My if statement isn't working even when condition is met. Roblox Lua

So here is the rundown of my code:

while _waveActive do
    wait(1)
    for i, _spwn in pairs(_spawns:GetChildren()) do
        if _spwn:IsA("BasePart") and _zombsLeft ~= 0 then
            local _zombCopy = game.ReplicatedStorage["Zombie"]:Clone()

            _zombCopy.Parent = game.Workspace
            _zombCopy.HumanoidRootPart.CFrame = CFrame.new(_spwn.Position + Vector3.new (0,3,0))
            _zombsLeft -= 1
            print(_zombsLeft)

        end
    end
end

if _zombsLeft <= 0 then
    _waveActive = false 
    _wave += 1
    _zombsLeft = 10 * _wave
    print ("New Round with Zombies Left: " .. _zombsLeft)
    wait(10)
    _waveActive = true
    print("Successfully started new round.")
end

Essentially everything works with the while loop but once _zombsLeft = 0 (being confirmed by print(_zombsLeft)) my if statement doesn't work. I have tried to put before and after the while loop just to make sure and still nothing. This is probably an obvious error but I can't find it for the life of me.

Also, my code is messy, sorry.

EDIT: To clarify I mean the if statement outside the loop.

Upvotes: 0

Views: 384

Answers (1)

Kylaaa
Kylaaa

Reputation: 7188

The issue is that you have a while loop that never escapes. Your code never actually gets to the if _zombsLeft <= 0 then check.

Based on the code, it looks like you're trying to do 3 things :

  1. Spawn zombies when a wave starts.
  2. Wait for 10 seconds.
  3. Increment the wave counter and start back over again.

You can accomplish this by restructuring your while-loop to include the if _zombsLeft <= 0 then check, or you can make it so that your _zombsLeft check is always running, just like your while-loop. The second option is closest to your existing code, and you can use the RunService.Heartbeat event to trigger code to fire every time the engine ticks. So try something like this :

--local _spawns = some folder in the workspace with spawn points 
local _wave = 0
local _waveActive = false
local _shouldSpawnZombies = false
local _zombsLeft = 0
local _countdownToNextRound = 10.0 --seconds
local _zombieTemplate = game.ReplicatedStorage["Zombie"]
local RunService = game:GetService("RunService")

-- create a helper function for spawning lots of zombies
local function spawnZombies(numToSpawn)
    -- NOTE - all items in _spawns are assumed to be a BasePart
    local spawnPoints = _spawns:GetChildren()
    local totalSpawnPoints = #spawnPoints

    -- spawn zombies at each spawn point
    while numToSpawn > 0 do
        -- select a spawn point for the zombie
        local spwn = spawnPoints[numToSpawn % totalSpawnPoints]

        -- create the zombie
        local zombCopy = _zombieTemplate:Clone()
        zombCopy.Parent = game.Workspace
        zombCopy.HumanoidRootPart.CFrame = CFrame.new(spwn.Position + Vector3.new (0,3,0))
        
        -- listen for when a zombie dies
        zombCopy.Humanoid.Died:Connect(function()
            _zombsLeft -= 1
        end)

        numToSpawn -= 1
        _zombsLeft += 1
    end
end


-- create a loop that always checks when to spawn more zombies
RunService.Heartbeat:Connect(function()
    if _shouldSpawnZombies then
        _shouldSpawnZombies = false
        spawnZombies(10 * _wave)
        print ("New Round with Zombies Left: " .. _zombsLeft)
    end
end

-- create another loop that holds the game's state machine
RunService.Heartbeat:Connect(function(delta)
    if _waveActive then
        -- check if all the zombies have been killed
        if _zombsLeft <= 0 then
            _waveActive = false
        end
    else
        -- this round is over, start the countdown to the next round
        if _countdownToNextRound >= 0.0 then
            _countdownToNextRound -= delta
        else
            -- the countdown has ended, reset the timer and start the next wave
            _countdownToNextRound = 10.0
            _wave += 1

            -- NOTE - if this was all in one loop, you would put your spawnZombies logic here...
            _shouldSpawnZombies = true
            _waveActive = true
            print("Successfully started wave #", _wave)
        end
    end
end)

There is no reason these need to be in two separate connections. In fact, the logic is needlessly complicated by the addition of an extra heartbeat connection, and I've included a note where you could merge the two.

However, for the sake of example, I've written this code to show how two sets of logic that are intended to always be running can be connected to the Heartbeat signal and co-exist.

Upvotes: 1

Related Questions