GetPropertyChangedSignal firing multiple times

Hello, I am running into a bug I am unsure how to fix. I have this script below, in which when the zombiesAlive value is 0 the next round will proceed and +1 is added to the wave value.

The issue is, if i have multiple zombies that a player kills at the same time, for example with a grenade, the function seems to repeat the amount of zombies that were killed, thus increasing the wave more than once.

For example, If the player is on round 1, and kills the last 3 zombies at the same time, the wave will then proceed to round 4 instead of round 2.

I am assuming this is because it gets connected to “0” multiple times? Here is the code:

zombiesAlive:GetPropertyChangedSignal("Value"):Connect(function()

	if #collectionservice:GetTagged("Alive") == 0 then

		return

	end

	if zombiesAlive.Value == 0 then

		workspace.RoundEnd:Play()

		wait(10.8)

		workspace.Roundstart:Play()

		for i, Player in pairs(game.Players:GetPlayers()) do

			if not Player:GetAttribute("Ready") then

				continue

			end

			local Character = Player.Character

			if Character == nil or Character.PrimaryPart == nil  then
				Player:LoadCharacter()
				continue
			end

			if Player.Team == game.Teams.Players then 
				--print "ignore active players"

			else


print "new players"


				local Backpack = Player:WaitForChild("Backpack")

				if wave.Value >= 10 then

					Player.leaderstats.Money.Value = 5000

				else



					Player.leaderstats.Money.Value = 500 * wave.Value

				end

				collectionservice:AddTag(Player, "Alive") 

				Character:WaitForChild("Torso").CFrame = workspace.Map:FindFirstChildOfClass("Model").Spawn.CFrame * CFrame.new(0,2,0)

				Player.Team = game.Teams.Players

				Character.SetCamera.Enabled = true




					
				
				Player.PlayerGui.MainGui.MenuBackground.Visible = false 
				Player.PlayerGui.MainGui.MainBackground.Visible = false

				print (Player.PlayerGui.MainGui.MenuBackground.Visible)
				print (Player.PlayerGui.MainGui.MainBackground.Visible)

				Player.PlayerGui.Cash.Enabled = true
				Player.PlayerGui["Health Gui"].Enabled = true

				-----------------------------------------------OLD LOADHAND HANDLE-----------------------------------------------
				--////////////////////////////////////////////////////////////////

				Character.WeaponHandler.Primary.Value = Player.CurrentGun.Value

				Character.WeaponHandler.CurrentWeapon.Value = "Primary"


				--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
				-----------------------------------------------OLD LOADHAND HANDLE-----------------------------------------------

				if #collectionservice:GetTagged("Alive") > 1 then

					workspace.Map.Normal.QuickRevive.Part.ProximityPrompt.Enabled = true
					workspace.Map.Normal.QuickRevive.Part.ProximityPrompt.ObjectText = "$1500"
					workspace.Map.Normal.QuickRevive.Part.ProximityPrompt.Price.Value = 1500

				else

					workspace.Map.Normal.QuickRevive.Part.ProximityPrompt.ObjectText = "$500"
					workspace.Map.Normal.QuickRevive.Part.ProximityPrompt.Price.Value = 500

				end

				for i, Object in pairs(Backpack:GetChildren()) do
					if Object.Name == Player.CurrentGun.Value then
						Player.Character.Humanoid:EquipTool(Object)
					end
				end

			end
		end
		wave.Value += 1

		zombieCount.Value = 0.000058 * (wave.Value)^3 + 0.074032 * (wave.Value)^2 + 0.718119 * (wave.Value) + 14.738699 
		zombiesAlive.Value =0.000058 * (wave.Value)^3 + 0.074032 * (wave.Value)^2 + 0.718119 * (wave.Value) + 14.738699 

		if wave.Value > 9 then

			game.ServerStorage.Zombie.Humanoid.Health = game.ServerStorage.Zombie.Humanoid.Health * 1.1

		else

			game.ServerStorage.Zombie.Humanoid.Health = game.ServerStorage.Zombie.Humanoid.Health + 100

		end

		if game.ReplicatedStorage.Values.DogRound.Value == true then --Doggies

			game.ReplicatedStorage.Values.DogsLeft.Value = 4 * #collectionservice:GetTagged("Alive")

			zombieCount.Value = 4 * #collectionservice:GetTagged("Alive")
			zombiesAlive.Value = 4 * #collectionservice:GetTagged("Alive")

		else

			zombieCount.Value = 0.000058 * (wave.Value)^3 + 0.074032 * (wave.Value)^2 + 0.718119 * (wave.Value) + 14.738699 --COD zombies formula
			zombiesAlive.Value =0.000058 * (wave.Value)^3 + 0.074032 * (wave.Value)^2 + 0.718119 * (wave.Value) + 14.738699 

		end 

	end

end)

Hello!

To start you can figure out what about this is firing multiple times by including print statements. This way you can find out exactly what is causing the issue.

I am also wondering if you should use elseif when checking for collectionservice tag then zombies alive value so that the priority is put onto the return if there is nobody left instead of potentially firing the second thing before the game processes that the first thing should be happening.

Definitely try the print statements thing first though, and if you are still unsure don’t be afraid to reply!

Hopefully this helps!

I actually did some prints and thats how i found out the function was repeating! I would print the wave.Value and it would print (1) (2) (3) (4) if i killed 3 zombies at once at the end of a round, like it was restarting the function.

So i should do elseif #collectionservice:GetTagged(“Alive”) == 0 then … and leave everything else the same?

EDIT: moved the elseif statement to the correct spot, but no changes unfortunately

You’ll need to add a debounce, which is a variable used to tell if something already happened and shouldn’t happen again.

So for your code that would look something like:

local isRoundOver = false

zombiesAlive:GetPropertyChangedSignal("Value"):Connect(function()
    ...

    -- A round can only start if the round isn't already over
    if zombiesAlive.Value == 0 and not isRoundOver then
		-- The round ended, so we record that so other calls know not to end it again
		isRoundOver = true
		workspace.RoundEnd:Play()

		wait(10.8)

		workspace.Roundstart:Play()
		-- A new round started, so now the round can end again
		isRoundOver = false  -- Ideally this would go after you add more zombies and zombiesAlive.Value is greater than 0
		...

I agree with the debounce and optimized the script a bit.

local debounce = false
local function onZombiesAliveChanged()
    if debounce or zombiesAlive.Value > 0 then return end
    debounce = true

    workspace.RoundEnd:Play()
    wait(10.8)
    workspace.Roundstart:Play()

    local players = game.Players:GetPlayers()
    local newZombieCount = 0.000058 * (wave.Value + 1)^3 + 0.074032 * (wave.Value + 1)^2 + 0.718119 * (wave.Value + 1) + 14.738699

    for _, player in ipairs(players) do
        if not player:GetAttribute("Ready") then continue end

        local character = player.Character
        if not character or not character.PrimaryPart then
            player:LoadCharacter()
            continue
        end

        if player.Team == game.Teams.Players then
            -- Ignore active players
        else
            local backpack = player:WaitForChild("Backpack")
            player.leaderstats.Money.Value = wave.Value >= 10 and 5000 or 500 * wave.Value

            collectionservice:AddTag(player, "Alive")
            character:WaitForChild("Torso").CFrame = workspace.Map:FindFirstChildOfClass("Model").Spawn.CFrame * CFrame.new(0, 2, 0)
            player.Team = game.Teams.Players
            character.SetCamera.Enabled = true

            local playerGui = player.PlayerGui
            playerGui.MainGui.MenuBackground.Visible = false
            playerGui.MainGui.MainBackground.Visible = false
            playerGui.Cash.Enabled = true
            playerGui["Health Gui"].Enabled = true

            local weaponHandler = character.WeaponHandler
            weaponHandler.Primary.Value = player.CurrentGun.Value
            weaponHandler.CurrentWeapon.Value = "Primary"

            local proximityPrompt = workspace.Map.Normal.QuickRevive.Part.ProximityPrompt
            if #collectionservice:GetTagged("Alive") > 1 then
                proximityPrompt.Enabled = true
                proximityPrompt.ObjectText = "$1500"
                proximityPrompt.Price.Value = 1500
            else
                proximityPrompt.ObjectText = "$500"
                proximityPrompt.Price.Value = 500
            end

            for _, object in ipairs(backpack:GetChildren()) do
                if object.Name == player.CurrentGun.Value then
                    player.Character.Humanoid:EquipTool(object)
                end
            end
        end
    end

    wave.Value += 1
    zombieCount.Value = newZombieCount
    zombiesAlive.Value = newZombieCount

    local healthChange = wave.Value > 9 and game.ServerStorage.Zombie.Humanoid.Health * 1.1 or game.ServerStorage.Zombie.Humanoid.Health + 100
    game.ServerStorage.Zombie.Humanoid.Health = healthChange

    if game.ReplicatedStorage.Values.DogRound.Value then
        local dogCount = 4 * #collectionservice:GetTagged("Alive")
        game.ReplicatedStorage.Values.DogsLeft.Value = dogCount
        zombieCount.Value = dogCount
        zombiesAlive.Value = dogCount
    end

    debounce = false
end

zombiesAlive:GetPropertyChangedSignal("Value"):Connect(onZombiesAliveChanged)

About as much as I think I can get away with without being able to test.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.