While Loops Stack on each other

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! What is the issue? Include screenshots / videos if possible!

I have a tool that when it is equipped, it will activate the tool automatically. When the tool is activated, it will start a loop to change color to random colors. A boolean of “Activated” is true when equipped, and false when unequipped. For some reason, the loops stack on each other when you equip and unequip even though Activated gets set to false, therefore ending that loop, when you unequip.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Yes, I followed a tutorial. I have not looked much on devforum except for a relevant post about Tools.
    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 Tool = script.Parent
local ToolSound = Tool.EquippingSound

local Activated = false


Tool.Equipped:Connect(function()
	ToolSound:Play()
	Tool:Activate()
end)

Tool.Activated:Connect(function()
	Activated = true
	
	Tool:ScaleTo(.5)
	
	
	while Activated do
		Tool.Handle.BrickColor = BrickColor.random()
		task.wait(1)
		
	end

end)

Tool.Unequipped:Connect(function()
	Activated = false 
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.

why are u activating the tool the moment u equipped it?

Any time you are using a :Connect(function() - these run in a new thread, basically. So you could call it multiple times, and it will create your loop multiple times.

To prevent that, you can add a check to the beginning of the function to see if Activated == false first, otherwise, it will just make a repeat loop any time you call the function. Example

Tool.Activated:Connect(function()
	if Activated == false then --make sure bool is false before starting
		Activated = true

		Tool:ScaleTo(.5)

		while Activated do 
			Tool.Handle.BrickColor = BrickColor.random()
			task.wait(1)

		end
	end
end)

why are u activating the tool in the equipped function, just make new function for color purposes and connect that with equipped function, also the reason ur function is stacking is First: u didnt put

local Activated = false
Tool.Activated:Connect(function()
	if Activated == true then return end
	Activated = true
end)

and second is because ure Requipping the tool faster than the task.wait(1), therefore it did not got to the while condition of Activated before u equip again

Even if i made it run the code when i equip instead of putting it in the Tool.Activate event, the same occurs no difference

Ok i see, i did

while Tool.Activated do
print(“loop”)
Tool.Handle.BrickColor = BrickColor.random()
task.wait(1)
end

Instead of firing a loop every event, I made it more simple and looped only while the tool is activated

local Tool = script.Parent
local ToolSound = Tool.EquippingSound

local Activated = false

local Debounce = false
local function ChangeColor()
	Activated = true
	if Debounce == true then return end
	Debounce = true
	Tool:ScaleTo(.5)
	
	local Count = 1
	while Activated == true do
		Tool.Handle.BrickColor = BrickColor.random()
		task.wait(1)
	end
	Debounce = false
end

Tool.Equipped:Connect(function()
	ToolSound:Play()
	ChangeColor()
end)

Tool.Activated:Connect(function()

end)

Tool.Unequipped:Connect(function()
	Activated = false 
	Tool:ScaleTo(1)
end)

If ur script is already working fine, ignore this reply

Well issue here is the loop holds up everything because if a player were to spam equip and unequip the tool would not shrink down because the loop in ChangeColor() is still on

This works,
while Tool.Activated do print(“loop”) Tool.Handle.BrickColor = BrickColor.random() task.wait(1) end

but this below does not. Not sure why (loops worked tho):
while Activated do
print(“loop”)
Tool.Handle.BrickColor = BrickColor.random()
task.wait(1)
end

Oh u wanted the tool to shrink whenever the player equips it, and not only when the colorchanging began, in that case, just movethe Tool:ScaleTo(0.5) above the if Debounce == true then return end

It still stacks the loop. Its strange that nothing works when i check with the Activated variable, but works with Tool.Activated

local Tool = script.Parent
local ToolSound = Tool.EquippingSound

local Activated = false

local Debounce = false
local function ChangeColor()
	Activated = true
	Tool:ScaleTo(0.5)
	if Debounce == true then return end
	Debounce = true
	
	local Count = 1
	while true do
		if Activated == false then break end
		Tool.Handle.BrickColor = BrickColor.random()
		task.wait(1)
	end
	Debounce = false
end

Tool.Equipped:Connect(function()
	ToolSound:Play()
	ChangeColor()
end)

Tool.Activated:Connect(function()

end)

Tool.Unequipped:Connect(function()
	Activated = false 
	Tool:ScaleTo(1)
end)

1 Like

I figured it out two replies ago, by the way these dont work. One that was just sent by @Veexas now works its just theres a more simple way to do it.

local Tool = script.Parent
local ToolSound = Tool.EquippingSound

local Activated = false

Tool.Equipped:Connect(function()
Tool:Activate()

end)

Tool.Activated:Connect(function()
Tool:ScaleTo(.5)
Activated = true
end)

Tool.Unequipped:Connect(function()
Activated = false
Tool:ScaleTo(1)
end)

while Tool.Equipped do
task.wait(1)
Tool.Handle.BrickColor = BrickColor.random()
print(“loop”)
end

1 Like

great - cause i js realised your problem - if you could pls click on the post u found was the solution!

local Tool = script.Parent
--local ToolSound = Tool.EquippingSound

local Activated = false

Tool.Equipped:Connect(function()
	--ToolSound:Play()
end)

Tool.Activated:Connect(function() --//wehn u click
	
	if not Activated then
		Activated = true
	else
		return
	end

	Tool:ScaleTo(0.5)



	while Activated do
		Tool.Handle.BrickColor = BrickColor.random()
		task.wait(1)
		if not Activated then -- //same as || if Activated == false then
			
			-- //what u want to add before it breaks.
			
			break -- //Stops the while loop
		end
	end
	

end)

Tool.Unequipped:Connect(function()
	Activated = false 
end)

This way is much more simple. My question now though is why this works
while Tool.Equipped do task.wait(1) Tool.Handle.BrickColor = BrickColor.random() print(“loop”) end
but replacing Tool.Activated with the activated variable makes it not work
while Activated do task.wait(1) Tool.Handle.BrickColor = BrickColor.random() print(“loop”) end

uhh whats the difference though brickcolor.random works

Local Activated variable is meant.

Tool.Equipped it iterates it knowing when u are equipping tool, but yes that’s a simple way to go. Remember to mark it as a solution on your topic.

1 Like

no that one doesnt work, forget that.

Ok I Will do, thanks :+1:

Makes sense now

1 Like

the thing is that simple isnt very accurate, it can cause stacking when u requipping quick, and if this script right here is what inside urs, the “while too.Equipped do” wont start because nothing triggers it and when it breaks, it breaks forever

unless theres more in ur script than what this shows

Wait what isnt accurate, because mine works, however my friend said while tool.Equipped do
is the same as while true do because tool.Equipped is a true value. Is that true