How to break a while loop when a part is touched?

Hey everyone! So today, I was scripting for fun, just to practice. I cam across a part where I wanted to have my flickering lights stop when a part is touched, but the code is in a while loop. Does anyone know how I can break this loop? I know you need to use “Break” but I just don’t know how, and where to use it. Here is my code…

--//Variables//--
local lights = {
	light = game.Workspace.Light;
	light2 = game.Workspace.Light2
}

local longlegParts = {
	head = game.Workspace.SCP.FalseHead;
	headdecal = game.Workspace.SCP.FalseHead.Decal;
	leftarm = game.Workspace.SCP.leftarm;
	leftleg = game.Workspace.SCP.leftleg;
	rightarm = game.Workspace.SCP.rightarm;
	rightleg = game.Workspace.SCP.rightleg;
	torso = game.Workspace.SCP.Torso
}

local detector = game.Workspace.detector

--//Main Code//--

while true do
	wait(1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(0.1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(1)
end


local function TParts()
	for i,v in pairs(longlegParts) do
		v.Transparency = 0
	end
end

detector.Touched:Connect(TParts)

If anyone knows how to make this work, please let me know!

4 Likes

Use a condition in the loop.

local touched = false
while not touched do
    blah
end

local function TParts()
    touched = true
    blah
end

in the while true do part, replace the true with a true/false variable. make it so when you touch the part, it make the variable go false

1 Like

K, now something seems to be wrong with my script, my Print doesn’t even print when the part touches to make sure that it runs.

--//Services//--
local TweenService = game:GetService("TweenService")

--//Variables//--
local lights = {
	light = game.Workspace.Light;
	light2 = game.Workspace.Light2
}

local longlegParts = {
	head = game.Workspace.SCP.FalseHead;
	headdecal = game.Workspace.SCP.FalseHead.Decal;
	leftarm = game.Workspace.SCP.leftarm;
	leftleg = game.Workspace.SCP.leftleg;
	rightarm = game.Workspace.SCP.rightarm;
	rightleg = game.Workspace.SCP.rightleg;
	torso = game.Workspace.SCP.Torso
}

local detector = game.Workspace.detector

--//Tweening//--

local info = TweenInfo.new(1,Enum.EasingStyle.Linear,Enum.EasingDirection.Out)

local properties = {CFrame = CFrame.new(21.52, 6, -41.38)}
local prop = {CFrame = CFrame.new(21.52, 6, -2.61)}

local tween1 = TweenService:Create(longlegParts.torso,info,properties)
local tween2 = TweenService:Create(longlegParts.torso,info,prop)


--//Main Code//--
local touched = false
while not touched do
	wait(1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(0.1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(1)
end

detector.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		touched = true
		print("Part Touched!")
		for i,v in pairs(longlegParts) do
			v.Transparency = 0
		end
	end
end)

You can use a break variable/function into the loop as using break will automatically stop the loop at a certain point like for instance, at the bottom or last piece of the loop to stop there.

Using a debounce like the users who have replied above with debounce = false/true is good, but it doesn’t work with a while true do loops well as it somewhat works when it’s outside the loop and not in it in some cases.

Some example with using the break condition:

local part = script.Parent

while true do
	part.BrickColor = BrickColor.Random()
	wait(1)
	
	if part.BrickColor == BrickColor.Black() then
		break
	end
end

Or:

local part = script.Parent

while true do
	part.BrickColor = BrickColor.Random()
	wait(1)
	
	break
end

Whole script seems hard for me to type and copy and add a break, feel free to add a break at the end of the loop.

For more info about loops and how to stop them in different function notations, you can read this article: Loops

Your Touched event listener is unreachable. Bind the event before starting the loop.

local toggle = false
detector.Touched:Connect(function()
  if toggle == false then
     toggle = true
  end
end)

while toggle == false do

	wait(1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(0.1)
	lights.light.Material = Enum.Material.Neon
	wait(0.1)
	lights.light.Material = Enum.Material.Plastic
	wait(1)
end

Im not sure this will work but maybe it will work?

2 Likes

Be sure to have the touched event code before the while loop, otherwise the code after the loop will never be reached. Try something like this:

local touched = false
detector.Touched:Connect(function()
	--You can check if it's a player or character that touched the detector
	touched = true
end)

function changeLights(waittime,material)
	wait(waittime)
	-- Check if it has been touched
	if not touched then
		-- Make light designated material
		lights.light.Material = material
	end
end

while true do
	changeLights(1,Enum.Material.Neon)
	changeLights(0.1,Enum.Material.Neon)
	changeLights(0.1,Enum.Material.Plastic)
	changeLights(0.1,Enum.Material.Neon)
	changeLights(0.1,Enum.Material.Plastic)
	wait(1)
end

This makes it so that if it is touched, it will stop flickering. If the variable touched becomes false again, the light will yet again flicker.