How to add cooldown to pair loops

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 a cloaking device that makes people invisible with a cooldown

  2. What is the issue? Include screenshots / videos if possible!
    I added a script that uses for pair loops to make the player invisible upon pressing mouse2button. But even though I already added debounce, the loop still starts when the debounce is false

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried adding debounce in both the server and local script

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 Script

local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Char = game.Players.LocalPlayer.Character
local CanCloak = true

UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		if CanCloak == true then
			CanCloak = false
			script.Parent.CloakEvent:FireServer()
			for _, descendants in pairs(Char:GetDescendants()) do
				if descendants:IsA("BasePart") and descendants.Name ~= "HumanoidRootPart" and not CanCloak then
					local TweenA = TweenService:Create(descendants, TweenInfo.new(1), {Transparency = 0.75})
					Char.Head.face.Transparency = 0.75

					script.Parent.Cloak:Play()
					TweenA:Play()
				end
			end
		else
			script.Parent.DeCloakEvent:FireServer()
			wait(1)
			CanCloak =true
		end
	end
end)

Server Script

script.Parent.Parent.Equipped:Connect(function()
	script.Parent.CloakEvent.OnServerEvent:Connect(function(player)
		local Char = player.Character
		
		for _, descendants in pairs(Char:GetDescendants()) do
			if descendants:IsA("BasePart") and descendants.Name ~= "HumanoidRootPart"  then
				local TweenA = TweenService:Create(descendants, TweenInfo.new(1), {Transparency = 1})
				Char.Head.face.Transparency = 1

				script.Parent.Cloak:Play()
				TweenA:Play()
			end
		end
	end)
end)

script.Parent.Parent.Equipped:Connect(function()
	script.Parent.DeCloakEvent.OnServerEvent:Connect(function(player) 
		local Char = player.Character

		for _, descendants in pairs(Char:GetDescendants()) do
			if descendants:IsA("BasePart") and descendants.Name ~= "HumanoidRootPart" then
				local TweenA = TweenService:Create(descendants, TweenInfo.new(1), {Transparency = 0})
				Char.Head.face.Transparency = 0

				script.Parent.Decloak:Play()
				TweenA:Play()
			end
		end
	end)
end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like

Alright, well I am having a touch of a rough time here I can help you understand the concept of your cool down.

I highly suggest finding and or writing your own way of managing timed events but.

You have a bool that represents if the thing the player did is on cool down or not. We check this each time they attempt to perform the action. If coolingDown then it will immediately bounce out and nothing else will happen.

When we do pass over it, we immediately set it, in that same time, you will want to add something to Heartbeat or Stepped, and incrament up the DeltaTime until it >= the cool down value. When you hit that, you clear it out, and then set the cool down that this system is tracking back to false and it can be used again.

track this independently on the server and the client, and the client is your first line of defense to block it, but if somehow it gets fired up to server, the server will check it’s own cool down timer and not allow the action to move forward.

That’s the essentials of “cool down”. I don’t know what you mean by doing it “in pairs” situation because really it should trip off right before you do the thing that the cooldown stands for. So it wont interrupt the actual process just stop the process from happening again till the cool down is complete.

The issue with your script isn’t " How to add cooldown to pair loops", but more about correctly implementing a debounce mechanism to manage the cloaking action. The check for CanCloak inside the for loop was redundant and logically incorrect. Once the loop starts, it should not need to check the CanCloak flag again for each descendant. The correct client script should look like this:

local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Char = game.Players.LocalPlayer.Character
local CanCloak = true

UserInputService.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton2 then
        if CanCloak then
            CanCloak = false
            script.Parent.CloakEvent:FireServer()
            for _, descendant in pairs(Char:GetDescendants()) do
                if descendant:IsA("BasePart") and descendant.Name ~= "HumanoidRootPart" then
                    local TweenA = TweenService:Create(descendant, TweenInfo.new(1), {Transparency = 0.75})
                    Char.Head.face.Transparency = 0.75
                    script.Parent.Cloak:Play()
                    TweenA:Play()
                end
            end
        else
            script.Parent.DeCloakEvent:FireServer()
            wait(1)
            CanCloak = true
        end
    end
end)

Pretty much, your script is long for something that makes player invisible like ability

First of all, you shouldn’t debounce on Client, rather server, how to do that?

You should create module called Debounce and few functions to it like

function Debounce:Add(player,debounce,time)
  Debounce[player][debounce] = tick() + time
end

Then you do:

if tick() > Debounce[player].Cloak then 
  --code
end

Also you can use simply:

for i,v in table do
  --code
end

pairs works almost the same, but in this case it’s not needed

what does the table represent?

Local script

local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Player = game.Players.LocalPlayer
local Char = Player.Character or Player.CharacterAdded:Wait()
local CanCloak = true
local CooldownTime = 5 -- Set your cooldown time here

local function cloakCharacter()
    for _, descendant in pairs(Char:GetDescendants()) do
        if descendant:IsA("BasePart") and descendant.Name ~= "HumanoidRootPart" then
            local TweenA = TweenService:Create(descendant, TweenInfo.new(1), {Transparency = 0.75})
            TweenA:Play()
        end
    end
    if Char:FindFirstChild("Head") and Char.Head:FindFirstChild("face") then
        Char.Head.face.Transparency = 0.75
    end
end

local function decloakCharacter()
    for _, descendant in pairs(Char:GetDescendants()) do
        if descendant:IsA("BasePart") and descendant.Name ~= "HumanoidRootPart" then
            local TweenA = TweenService:Create(descendant, TweenInfo.new(1), {Transparency = 0})
            TweenA:Play()
        end
    end
    if Char:FindFirstChild("Head") and Char.Head:FindFirstChild("face") then
        Char.Head.face.Transparency = 0
    end
end

UserInputService.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton2 then
        if CanCloak then
            CanCloak = false
            script.Parent.CloakEvent:FireServer()
            cloakCharacter()
            script.Parent.Cloak:Play()
            wait(CooldownTime)
            CanCloak = true
        else
            script.Parent.DeCloakEvent:FireServer()
            decloakCharacter()
            script.Parent.Decloak:Play()
        end
    end
end)

Server Script

local TweenService = game:GetService("TweenService")

local function handleCloak(player)
    local Char = player.Character
    if Char then
        for _, descendant in pairs(Char:GetDescendants()) do
            if descendant:IsA("BasePart") and descendant.Name ~= "HumanoidRootPart" then
                local TweenA = TweenService:Create(descendant, TweenInfo.new(1), {Transparency = 1})
                TweenA:Play()
            end
        end
        if Char:FindFirstChild("Head") and Char.Head:FindFirstChild("face") then
            Char.Head.face.Transparency = 1
        end
    end
end

local function handleDecloak(player)
    local Char = player.Character
    if Char then
        for _, descendant in pairs(Char:GetDescendants()) do
            if descendant:IsA("BasePart") and descendant.Name ~= "HumanoidRootPart" then
                local TweenA = TweenService:Create(descendant, TweenInfo.new(1), {Transparency = 0})
                TweenA:Play()
            end
        end
        if Char:FindFirstChild("Head") and Char.Head:FindFirstChild("face") then
            Char.Head.face.Transparency = 0
        end
    end
end

script.Parent.CloakEvent.OnServerEvent:Connect(handleCloak)
script.Parent.DeCloakEvent.OnServerEvent:Connect(handleDecloak)