Confused with loops and functions

Hey there!

So i’m really confused with loops and functions. During a while loop, if the player presses an image button, i want for a function to be triggered. Where do i put the function? Outside the loop? Inside the loop?

This is what it looks like inside the loop:

while deb == true do
	script.Parent.MouseButton1Click:Connect(function()
		deb = false
		Animation1:Cancel()
		Animation3:Cancel()
		camera.CFrame = workspace.CameraE1.CFrame
		script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
	end)
	camera.CFrame = Camera1.CFrame
	Animation1:Play()
	Animation1.Completed:Wait()
	camera.CFrame = Camera5.CFrame
	Animation3:Play()
	Animation3.Completed:Wait()
	camera.CFrame = Camera1.CFrame
end

(I’m not sure why the text is red :p)

I want for the script.Parent.MouseButton1Click:Connect(function() to be called while the loop is running.

Video: BUILDING STILL NEEDS WORK AND GUI IS ONLY THERE FOR TESTING PURPOSES.

Any help would really be appreciated

2 Likes

Events are listeners, they wait for something to happen then execute the function. This while loop is right now setting up many many events at once, rather than just waiting for the one to be triggered. What I would change is move the event outside, reference it with a variable it so it can be disconnected, then when the loop ends, do so.

local event_connection = script.Parent.MouseButton1Click:Connect(function()
		deb = false
		Animation1:Cancel()
		Animation3:Cancel()
		camera.CFrame = workspace.CameraE1.CFrame
		script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
	end)
while deb == true do
	camera.CFrame = Camera1.CFrame
	Animation1:Play()
	Animation1.Completed:Wait()
	camera.CFrame = Camera5.CFrame
	Animation3:Play()
	Animation3.Completed:Wait()
	camera.CFrame = Camera1.CFrame
end
event_connection:disconnect()
1 Like

I would just enable the button in the while loop in a separate script

1 Like

Thanks! That solves that, however, i have another problem.

For some reason the second time i call the function, the Click function just doesn’t work…

Here’s the full script:

local deb = true

local MainMenuExit = script.Parent.MouseButton1Click:Connect(function()
	deb = false
	Animation1:Cancel()
	Animation3:Cancel()
	camera.CFrame = workspace.CameraE1.CFrame
	script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
end)

local function MainMenuCamera()
	if deb == true then
		while deb == true do
			camera.CFrame = Camera1.CFrame
			Animation1:Play()
			Animation1.Completed:Wait()
			camera.CFrame = Camera5.CFrame
			Animation3:Play()
			Animation3.Completed:Wait()
			camera.CFrame = Camera1.CFrame
		end
	end
	MainMenuExit:disconnect()
end

game.ReplicatedStorage.PlayerAdded.OnClientEvent:Connect(function()
	print("PlayerAdded")
	deb = true
	MainMenuCamera()
end)

game.ReplicatedStorage.BackArrow.OnClientEvent:Connect(function()
	print("Fired")
	deb = true
	MainMenuCamera()
end)

The remote event works perfectly fine, iv’e tested it out.

It may have something to do with the ‘deb’ variable but i’m not sure what is it

Any help on that would be REALLY appreciated! :+1:

A variable assigned to a function? Maybe just get rid of the variable, I havent seen a variable being assigned to a function before.

Click function doesn’t work because it was disconnected. Reconnect like so:

local function MainMenuCamera()
    local MainMenuExit = script.Parent.MouseButton1Click:Connect(function()
		deb = false
		Animation1:Cancel()
		Animation3:Cancel()
		camera.CFrame = workspace.CameraE1.CFrame
		script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
	end)
	if deb == true then
		while deb == true do
			camera.CFrame = Camera1.CFrame
			Animation1:Play()
			Animation1.Completed:Wait()
			camera.CFrame = Camera5.CFrame
			Animation3:Play()
			Animation3.Completed:Wait()
			camera.CFrame = Camera1.CFrame
		end
	end
	MainMenuExit:disconnect()
end

That will make it work every time you call the function.

Iv’e tried that but got the same results. I’ll try @Styre_x’s method now.

this is actually a decently common practice when you need to disconnect a connection, it helps clean up memory and keep your game running smoothly. If you destroy the instances or the script you don’t need to disconnect the function, as roblox disconnects connections automatically. Wiki article is here: Events | Documentation - Roblox Creator Hub

1 Like

I still got the same results with your method too… This is really weird. Iv’e never had a problem that like this before. Ill upload a video to make the problem more clear and hopefully come up with a fix.

Be sure to only call :Disconnect() on connections that won’t be needed for a considerable amount of time, otherwise if

 script.Parent.MouseButton1Click

will fire fairly often, the :Disconnect() is pointless.

1 Like

I think I know why, deb isn’t being set to true when mainmenucamera is run again, :woman_facepalming: I have no clue how I didn’t notice that. Add

deb = true  

to the function before the loop starts.
Also with the while loop and if statement you can just do

if deb then
    while deb do
        --code
    end
end
1 Like

Still doesn’t work for some reason. The problem isn’t the MainMenu() function not running, its the MainMenuExit not working for some reason the second time. I may have a spelling error in the code, so just in case ill show you what i have at the moment:

local deb = true

script.Parent.MouseButton1Click:Connect(function()
	deb = false
	Animation1:Cancel()
	Animation3:Cancel()
	camera.CFrame = workspace.CameraE1.CFrame
	script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
end)

local function MainMenuCamera()
	deb = true
	local MainMenuExit = script.Parent.MouseButton1Click:Connect(function()
		deb = false
		Animation1:Cancel()
		Animation3:Cancel()
		camera.CFrame = workspace.CameraE1.CFrame
		script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
	end)
	if deb then
		while deb do
			camera.CFrame = Camera1.CFrame
			Animation1:Play()
			Animation1.Completed:Wait()
			camera.CFrame = Camera5.CFrame
			Animation3:Play()
			Animation3.Completed:Wait()
			camera.CFrame = Camera1.CFrame
		end
	end
	MainMenuExit:Disconnect()
end

game.ReplicatedStorage.PlayerAdded.OnClientEvent:Connect(function()
	print("PlayerAdded")
	MainMenuCamera()
end)

game.ReplicatedStorage.BackArrow.OnClientEvent:Connect(function()
	print("Fired")
	MainMenuCamera()
end)

I have a feeling it may have something to do with the :Disconnect(), as it wont auto fill when i type it out.

given you’re connecting to the click twice (once outside the function, and again inside it), you can try removing MainMenuExit lines

local function MainMenuCamera()
	while deb do
		camera.CFrame = Camera1.CFrame
		Animation1:Play()
		Animation1.Completed:Wait()
		camera.CFrame = Camera5.CFrame
		Animation3:Play()
		Animation3.Completed:Wait()
		camera.CFrame = Camera1.CFrame
	end
end

Also, Disconnect is the correct function, it just doesn’t autofill for some reason.

Oops didn’t see i had the click function twice. Thanks for pointing that out! :+1:

Still not working tho…Does Disconnect work in local scripts?

Also, could it be because its inside a function inside a function?:

game.ReplicatedStorage.BackArrow.OnClientEvent:Connect(function()
     print("Fired")
     script.Parent.Parent.Parent.Enabled = true
     MainMenuCamera()
end)

Disconnect is just a function that disconnects the connection, this explains it well: Events | Documentation - Roblox Creator Hub

a function inside a function works perfectly fine, I don’t know why it wouldn’t work now. Are there any errors? it might be something not firing, try adding prints everywhere until you find something that doesn’t print when it should and that is the troubled area.

2 Likes

Here’s the script with the print functions:

local deb = true

local function MainMenuCamera()
	deb = true
	local MainMenuExit = script.Parent.MouseButton1Click:Connect(function()
		print("Player has Clicked play, MainMenuExit Connect")
		deb = false
		Animation1:Cancel()
		Animation3:Cancel()
		camera.CFrame = workspace.CameraE1.CFrame
		script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
		script.Parent.Parent.Parent.Enabled = false
	end)
	if deb then
		while deb do
			print("Loop has started")
			camera.CFrame = Camera1.CFrame
			Animation1:Play()
			Animation1.Completed:Wait()
			camera.CFrame = Camera5.CFrame
			Animation3:Play()
			Animation3.Completed:Wait()
			camera.CFrame = Camera1.CFrame
			print("Loop has ended")
		end
	end
	MainMenuExit:Disconnect()
	print("Loop is broken, MainMenuExit Disconnected")
end

game.ReplicatedStorage.PlayerAdded.OnClientEvent:Connect(function()
	print("PlayerAdded, MainMenuCamera Begins")
	MainMenuCamera()
end)

game.ReplicatedStorage.BackArrow.OnClientEvent:Connect(function()
	print("Fired")
	script.Parent.Parent.Parent.Enabled = true
	MainMenuCamera()
end)

Here’s the output (sorry it’s small and low quality). Hopefully this should help! :+1:

Now that i’m looking at the output, i see a random ‘Loop has ended' under 'Player has Clicked play, MainMenuExitConnect’. But how is that possible? How can that print if deb = false? Shouldn’t the ‘if deb then’ not allow for that to be printed?

I am still trying to figure out how while loops fully work. :disappointed_relieved:

Loops run like this:

Loop starts, checks conditions, if conditions are false, terminate the loop.
Runs any code inside the loop, yielding if needed
goes back up to the start of the loop

anything at the end of the loop will still run even if the condition is false. The if statement is outside the loop, its quite redundant and only checks something the loop already checks. If deb is false, the loop won’t run anyway.
It looks like everything should work, but sometimes there are errors that are easier to fix by simply redoing the code. Here’s an attempt at making it work, if it doesn’t work PM me so we can fix it without clogging up this topic.

local Debounce = true

script.Parent.MouseButton1Click:Connect(function()
	Debounce = false
	Animation1:Cancel()
	Animation3:Cancel()
	camera.CFrame = workspace.CameraE1.CFrame
	script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = true
	script.Parent.Parent.Parent.Enabled = false
end)

local function Setup()
	script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = false
	script.Parent.Parent.Parent.Enabled = true
	Debounce = true
	while Debounce do
		camera.CFrame = Camera1.CFrame
		Animation1:Play()
		Animation1.Completed:Wait()
        --this breaks the loop, preventing it from running if debounce is false
		if not Debounce then
			break
		end
		camera.CFrame = Camera5.CFrame
		Animation3:Play()
		Animation3.Completed:Wait()
		camera.CFrame = Camera1.CFrame
	end
end

--event connections here

game.ReplicatedStorage.BackArrow.OnClientEvent:Connect(function()
	print("Fired")
	script.Parent.Parent.Parent.Enabled = true
	Setup()
end)

--I'd get rid of the playeradded event, as sometimes that might fire before this script loads.

Setup()
1 Like

You’re an absolute life saver. I was going through the code you rewrote (thank you by the way for actually taking your time on that) and i saw, script.Parent.Parent.Parent.Parent.IntermissionButtons.Enabled = false

Then i realised it had nothing to do with the code, rather disabling the intermission buttons. This is what the buttons look like:

The button wouldn’t press because the intermission buttons were in the way, and there was no sign it was the intermission buttons because i only allowed them to perform functions if the camera.CFrame was at the Intermission screen.

That was really unexpected, and a bit stupid of me.

Thank you so much, for maintaining your patience and helping me all the way through! I can’t thank you enough!:+1:

1 Like