I have a function to decrease the range of a PointLight over time.
spawn(function() local counter = 0 while counter < 10 do pl.Range = pl.Range * (1 - counter / 10) counter = counter + 1 wait() end end)
Is there a way to do this without having to use wait() and spawning a new function?
edit: I used spawn() as this function will run concurrently to many others in my game. Otherwise the scripts would pause just to wait for the light to be deleted
The Spawn
function creates a new thread for the thread scheduler to execute - it is for processing multiple actions at once. If you absolutely need to do two actions at once, what you're doing is fine.
The only alternative I may suggest is using the coroutine functions built into the API. Ultimately, these will produce the same outcome. But, coroutines are more powerful.
They allow you to be able to retrieve data outside of the initially defined thread(will give example)
You cannot yield the thread the spawn
function creates with the exception of internal yield functions (and wait
).
In other words, it is:
spawn(function() -- [FIRST NEW THREAD] print("hold on mydude, gotta go get something") end) local externalData = "Bob"; wait(10); spawn(function() -- [SECOND NEW THREAD] print("alright i'm back, the guy's name was: "..externalData") end)
vs:
local a = coroutine.create(function() -- [FIRST NEW THREAD] print("hold on mydude, gotta go get something"); local externalData = coroutine.yield(); print("alright i'm back, the guy's name was: "..externalData); end) local theInfoInTheOtherRoom = "Bob"; coroutine.resume(a); -- [PLAYING FIRST THREAD] wait(10); coroutine.resume(a,theInfoInTheOtherRoom); -- [STILL JUST THE FIRST THREAD]
See what I mean? It's one thread, rather than two threads.
Note that I know this situation doesn't seem relevant to yours, and that I am mainly providing an example as to why you might consider using coroutine functions rather than spawn
coroutine.yield
function will stop the thread until coroutine.resume
is called upon the thread, externally, and will return whatever arguments were passed with resumeSo, the coroutine equivalents to your code would be:
local count = coroutine.create(function() local counter = 0 while counter < 10 do pl.Range = pl.Range * (1 - counter / 10) counter = counter + 1 wait() end end) coroutine.resume(count);
local count = coroutine.wrap(function() local counter = 0 while counter < 10 do pl.Range = pl.Range * (1 - counter / 10) counter = counter + 1 wait() end end) count();