I want to make a while loop that breaks when a function is called,but i don't know how to do it! Here is the while loop of my script and the function that breaks the loop
while true do script.Parent.TweenableValue.Tween:Invoke(thing,'InOut','Quad',20,true) repeat wait() until value.Value==thing script.Parent.TweenableValue.Tween:Invoke(-thing,'InOut','Quad',20,true) repeat wait() until value.Value==-thing print'done' end function play() print'play' killplayer:FireServer() menuSound:Stop() button.Visible=false con:disconnect() script.Parent.ImageLabel.Visible=false script.Parent.Frame.BackgroundTransparency=0 --Break while loop end
Yes, but not in the same way you're trying to do. Loops won't execute the next line of code until whatever condition they're given is met. Therefore, using an infinite while true
statement will run the loop forever, never executing the code after the loop's block, meaning your function play
was never evaluated.
You typically don't want while loops running in different places (for this to even be possible, coroutines would be involved, which is a whole other story). Whatever it is you're trying to do, there's probably a much better solution for it.
To answer your question, though, you would want the condition of your while loop to be mutable (not constant). That way, you can change the variable the while loop is using as a condition, to terminate the loop next iteration. Example:
local running = true -- Create condition -- This is what I was talking about before, with the involvement of coroutines. While this is a solution, I highly don't recommend it for anything other than practice. spawn(function() while running do print("Loop is running") wait() end print("Stopped running") end) -- Some function that stops the loop outside of itself by setting 'running' to false local function stopRunning() running = false end -- Wait 1 second before stopping the loop wait(1) stopRunning()
The code above is just for practice, I don't recommend using it in any project you're working on. However, this would be the answer to your question. If need help understanding anything, just let me know.
Edit:
Creating a "pause and play" mechanic to a loop, would implement coroutines. You don't have to use them directly, but they're being used one way or another (with other functions like spawn), so I'm going include them in my example.
-- ~ ScriptGuider -- Library functions local create = coroutine.create local resume = coroutine.resume local yield = coroutine.yield local status = coroutine.status local floor = math.floor -- A pseudo instance to provide interface for a loop local loop = {} -- Local pause function, to be used within the loop's code. local function Pause() print("Loop paused from internal coroutine") loop.Running = false return yield() end -- Code that will be run within the while loop. loop.Code = function(t) print("Loop birth time: "..t.." seconds") Pause() -- Calling "Pause" to stop the loop until ran externally print("Picking up") -- Picks up where it left off when ran again wait(1) -- Wait 1 second each iteration end function loop:Run() local coro = self.Coro -- Using a debounce here so we can't resume and already running coroutine if not self.Running then self.Running = true -- Make sure we always have a coroutine to resume if not coro or coro and status(coro) ~= "suspended" then coro = create(function() local timestamp = tick() -- The actual running loop while self.Running do local elapsed = floor(tick() - timestamp) -- You could just "return true" from within the loop's "Code" function to stop the loop if loop.Code(elapsed) == true then print("Loop stopped from internal coroutine") break end end end) self.Coro = coro end resume(coro) end end -- Stop the loop from outside it's coroutine function loop:Stop() print("Loop stopped from external coroutine") self.Running = false end -- Run the loop loop:Run() wait(5) -- Stop the loop loop:Stop() wait(5) -- Run the loop again loop:Run()
Looks a bit complicated, as it should for a situation like this. This is probably the closest I could get to giving an example without making an entire task-scheduler. This basically just utilizes the yield
function of the coroutine library, which exits the code block's running state, and can be used to queue it up to later be resumed. During this intermediate state, the program can spend time handling other tasks so no time is wasted.