Is there an overall most efficient way to keep checking if a condition has happened?
I know two methods for achieving this:
while true do
wait()
if condition then
--code
end
end
or
local RunService = game:GetService("RunService")
RunService.RenderStepped:Connect(function()
if condition then
--code
end
end)
So my main question is asking, are these the only two ways to check something constantly? If not then what are the other ways, and which would be the most efficient?
something similar to Unity3D’s Update method if you are familiar with that
I completely understand what you are asking. I have also found my self in this situation many times where I need to check if a variable defined within my code has changed throughout time.
For example: If sprint energy has reduced to a value below 10
I’ve looked into it a lot and the best solution I have found is instead of using a variable defined in your code, change the variable to a value (like a StringValue) parented to your script, and set the variable to the value of that (string)value.
Example:
Old Code:
local sprintEnergy = 100 -- 100% spring energy
while true do
wait()
if sprintEnergy < 10 then
--code
end
end
New Code:
local sprintEnergyValue = Instance.new("IntValue", script)
sprintEnergyValue.Value = 100
sprintEnergyValue.Changed:Connect(function()
if sprintEnergy.Value < 10 then
-- Code
end
end)
Hope that helped! This is my solution every time I have this problem.
The solution Sentro gave looks rather haxy and isn’t the way I would go about doing it since I (and many other devs) try to not use any type of Value-Instances in our work. The other issue is if there are too many Instances being formed inside of a script that aren’t destroyed to allow the garbagecollector to take care of the rest, that’ll quickly eat up your memory-resources and will result in a server eventually lagging out then crashing.
To answer the actual question, this is my first method I use to wait until a condition changes since it’ll easily allow for more code to follow after it and can easily be reused without have to spawn a function:
I prefer using Heartbeat instead of RenderStepped since Heartbeat fires at the end of every frame which is further elaborated here a bit: Heartbeat, RenderStepped and Stepped Differences
local RunService = game:GetService("RunService")
local Connection
Connection = RunService.Heartbeat:Connect(function()
if condition then
--Code
Connection:Disconnect() --Makes the loop stop if you want it to
end
end)
This is the other way I go about doing it make the entire script stops until that condition has happened
repeat wait() --[[Other code here if you want ]] until condition
-- Rest of code
I try to avoid using while true do wait() print("IHazCodeHere") end since that means I’ll have to use break someplace to end the loop yet many still do it and their code runs fine. It simply comes down to what you are trying to achieve when checking a certain condition and where your variables that go with the condition are located.
Edit: If you need any help with making loops that check for a condition just send me a DM and I’ll help you figure out probably which one is the best to use.
while true do
wait()
if condition then
-- Code
end
end
Why would you yield pointlessly at the beginning of an iteration and why would you check a condition this way? The conditional statement of a while loop exists, which is to allow the loop to resume iterations until the condition has been met. Use that condition.
I personally feel like sentro’s idea heads in a more correct direction than NKM9’s. Making a check 30 or 60 times a second uses more cpu resources. I would hook up a function to a (remote or bindable event) or module script if the value is needed outside of the script. Otherwise I would do everything inside the script by using passthroughs.
local condition;
function Check()
if condition then --check condition
-- Code
end
end
function UpdateTheConditionalItem(NewValue)
condition = NewValue
Check()
end
Using UpdateTheConditionalItem(NewValue) we can check the value to see if it meets the condition every time it is updated. You can also hook this up in a module and require that module to move the condition between multiple scripts.
To answer your main question, those are more or less the only ways to check a condition constantly. Other permutations exist (using repeat instead of while, other events, etc), but those are the two basic models.
I suggest against doing either of them though. A better solution would be to use events and wait until they fire to run whatever code you want to run under that condition. It’s more elegant and wastes less time and memory.
As for which is most efficient, I’d like to make a note. You should absolutely avoid using wait() (with no arguments) whenever possible since the time it waits is actually variable. There’s a nice thread by Kampfkarren on that subject here. As a result, the better option of the two provided in your OP would be to use RenderStepped.