So, out of pure interest of testing my capabilities, I started replicating an interactive website on Roblox (more details on this will be on a different thread when it’s finished).
One of the things I need to do is make sure that during a specific time period, when something is clicked, the loop that function is in will be “reset”, so to speak.
I can think of doing this by utilising a click event with connection and disconnections, though it’s a bit finicky.
This part of the code, in a simplified form, is essentially doing this, so far:
while true do
button.MouseButton1Click:Wait()
-- appropriate code
local clicked = false
local connection = button.MouseButton1Click:connect(function()
clicked = true
-- appropriate frame control code
connection:disconnect()
end)
wait(x) -- where x is the time period
if clicked then connection:disconnect() break end
-- more code
end
In this code snippet, I’d be required to somehow restart the loop from within the function. I can think of this via wrapping the loop in a function and call the function when the button is clicked. Is there any better way to go about restarting the loop?
The only plausible way I can think of going back to the start of a loop would be something like this:
function RunLoop()
local Index = 0
while true do
if Index >= 3 then
print("Restarting loop, index will start a 1.")
RunLoop()
break
end
Index = Index + 1
print(Index)
wait(1)
end
end
RunLoop()
If you were to let that code run you will notice this output:
1
2
3
Restarting loop, index will start a 1.
1
2
3
Essentially you would want a function that starts the loop, and whenever you plan to restart the loop you would run the function (which will rerun the loop) and then do a break which stops the active loop.
There’s no point for the break with my knowledge of functions? Do correct me if I’m wrong!
When you run a function like in your case, it’ll never break, because when you run a function, it immediately goes through the function, then when it finishes, it’ll continue the code after it. Your code will constantly run the function again before the break.
Also, the question was asking if there was a better way to do this rather than “wrapping the loop in a function and call the function when the button is clicked”. Though, thanks for at least confirming that this method would work (unable to access studio right now to test my theory).
You’re actually correct, the break seems to not be required as the new loop will prevent the rest of the code from running in the first place.
I primarily quickly read over your post, but yes your current idea would work, I can’t think of many other solutions as programming languages like C++ have something called continue which gives this functionality whilst Lua does not.
I’ll try to think of some other solutions to make this functionality happen but currently what I’ve posted here is all I can think of.
Alright, you’re contribution is appreciated. Considering how many people have programmed in lua, I’d expect someone to at least have thought of a possible work-around. Worst comes to worst, I can just run it as a function.
For now, I’ll be going offline for at least 9 hours. Good luck!
You could wrap the loop in an outer loop and call break or have the click toggle a script on and off to restart it. But depending on what you’re trying to do perhaps there’s an easier way to achieve that.
So disabling a LocalScript and re-enabling it will cause it to restart? Didn’t realise that! (though it was probably obvious…)
I’m trying to make it so that if the players clicks a UI button before they’re meant to, the UI changes to say that it’s too soon and to click again in order to restart the “timer”/wait, however if you call a break within a function thats within a loop, it errors since there’s technically no loop to break.
I don’t think that turning a script on and off is the ideal solution.
What you should aim for is some kind of global count variable. When you click the button, it sets this to an arbitrary number and also begins a while loop that counts down from the variable to 0.
Since the variable is global, you can “go to the start of the loop” simply by resetting the variable to its original value anytime.
However, you do eventually need an end condition so you don’t have an infinite loop on your hands. That was the purpose of the break earlier. Alternatively, you can bake a conditional statement into a while loop
variable = 0
— function that triggers loop only if one isn’t already running
while variable > 0 do
— do stuff
wait(1)
variable = variable -1
end
Correct me if I’ve misunderstood what you’re trying to say.
Your code will essentially go to the “start” of the loop in the sense of how many times it runs.
What I wish to achieve is that it goes to the physical start of the loop, i.e. not running the rest of the code, but instead running the loop again.
In your snippet, even if you were to edit this variable’s value, it’ll continue the rest of the code before restarting the loop.
Also, the idea is that it’s exactly that, an infinite loop! This isn’t designed to go into a “playable” game, more like something I’m creating out of pure interest - hence it keeps repeating the same process until a (different) button is pressed to break the loop - which is already covered.
Sounds like you just want to store a timestamp then, no need for loops at all. If current time - stamp is not large enough you update stamp to be current time.
Hm, so going off the original code, it’d be something like the following?
local currentTime = tick()
local timeStamp = currentTime
local function updateStamps(val)
currentTime = tick()
if (currentTime - timeStamp) < val then
timeStamp = currentTime
return false
else
return turn
end
end
while true do
button.MouseButton1Click:Wait()
-- appropriate code
local connection = button.MouseButton1Click:connect(function()
if not updateStamps(5) then
-- appropriate frame control code
else
connection:disconnect()
end
end)
while tick()-timeStamp < 5 do game:GetService("RunService").RenderStepped:Wait() end
connection:disconnect()
-- more code
end
(Wrote this on the spot, may be logic errors etc, just an idea of how to implement)
You can do a loop in a loop, like a true gamer scripter. Wrap a while true do in a while true do. When the inner loop is broken using break, the outer loop resumes, and then promptly starts the inner loop again.
Like so:
while true do
--outer
while true do
wait()
--inner
end
print(”broken”)
end
How cheat-like! Nice idea - it revokes the need for having to wrap it in a function and call said function (as requested), though just replaces it with wrapping in a loop and adding a break.
@gullet That depends on what you mean by double click. I can see how you’d think that seeing as the loop first waits for a click, before later adding in another click event - however, there’s actually a delay in these two periods, sure players can double click to get past said two periods, but they can also wait between the two clicks and still get the same outcome - which is the idea.
After the first click, there’s a bunch of visual changes on the screen, they then have to wait an unknown period of time for another visual change to click again - if they click too early, the function assigned to the variable “connection” runs.
I’ll test both ideas (from gullet and konlon15) once I can get on studio (probably 30 mins - 3 hours).
Sounds like the easiest thing is to just have a click event that then checks if it’s the first or second click and how well timed it is, no need to to disconnect any events.
There is one solution you could use to achieve going to the start of a loop with what Lua has, you can possibly use repeat which would look like this:
a = 10
repeat
print("value of a:", a)
a = a + 1
until(a > 15)
It pretty much goes to the start of the loop each time if a condition is not met and once the condition is met it will end the loop. I don’t know if this would help your use case though.
Here is a flow diagram for how this works though:
This is probably not the most ideal solution though.
There are more clicks afterwards, if I don’t disconnect, I’ll have to make the function with it account for multiple scenarios - which I don’t particularly want to do. I intend to make the project open-source when it’s finished, and, honestly, that doesn’t look very pretty :P.
Feel free to explain in detail if you want possibly better methods to build it. In my mind it still sounds easier to have one event always connected and just handle that dynamically.
Yeah, I know how repeat statements work, I would have used one, but a prior post on a different thread has encouraged me to not use repeat statements as much because it can cause unnecessary yielding
i.e.
clicked = true
repeat wait(1) until clicked
Even though clicked is true, it still waits. Hence, I used another while loop with a RenderStepped:Wait() to minimise yields.