----------- Main
while true do -- server cannot detect .Ended()
changeSong() -- Set first song
if songLength ~= nil then
wait(songLength) -- server cannot detect .Ended()
sound:Destroy() -- garbage collection
end
end
I currently have this segment of code, and I want to wait until changeSong() returns a boolean to proceed to the next lines. Sort of like tween.Completed:wait(). I could have some sort of wait/repeat until loop, but that would slow down the thread and create lag, perhaps with unknown consequences.
I have a feeling coroutines may solve this, however I’m inexperienced in them and a better method might be revealed by posting.
The problem is that changeSong() is fired multiple times in the while loop.
while true do -- server cannot detect .Ended()
if changeSong() then
wait(songLength) -- server cannot detect .Ended()
sound:Destroy() -- garbage collection
end
end
Something like this has the same issue. I want to have something that will pause the program until true is returned. Not sure if it’s good advice in this case, but the reason I don’t want to use a repeat until loop is from Avoiding wait() and why. Maybe this is an exception
while true do
changeSong()
if changeSong == false then
elseif
if songLength ~= nil then
return
until(songLength).Value > 5 --example number
wait(1)
if songLength == nil then
Sound:Destroy()
end
end
end
as I’m not too experienced in the area your asking for I’m not too sure this will work if it doesn’t could you please post the output here?
Only events such as tween.Completed really run asynchronously (without extra work)
Calling the function will wait until it returns already. If changeSong has a wait(10) in it, then it will be at least 10 seconds before if songLength... runs.
If you want it to run at the same time and not wait to finish, use coroutines or spawn. spawn(changeSong)
Coroutines would not solve it. Your current code already solved the issue.
If you want to use the Boolean result, simply set a variable to the output,
yourBool = changeSong()
Code after this line will be executed after changeSong has completed.
I suspect you might be trapped in an XY problem where your actual issue is songLength not being defined or never updating to the new song, or some other similar issue.
With something like that, Found a song successfully! is printed multiple times when it’s expected to only once. I probably should have provided more of the script to better convey what I was having trouble with:
local songID -- Global
local sound -- Global
local songLength -- Global
local function changeSong()
local randIndex = randFromTable(music)
songID = music[randIndex]
sound = Instance.new('Sound', workspace) -- global for signals, garbage collection
sound.SoundId = 'rbxassetid://' .. tostring(songID)
sound.Name = "globalSound"
sound.Looped = false
sound.Volume = 0.3
songLength = sound.TimeLength -- global for end detection
local assets = {sound}
contentProvider:PreloadAsync( assets )
if checkCopyRight(songID) then
event:FireAllClients(sound) -- send as the audio changes, because client can't detect change on server objects very well
sound:Play()
print("\tFound a song successfully!")
return true
else
print("Recursing to find new song...")
changeSong() -- recursive
end
end
----------- Main
while true do -- server cannot detect .Ended()
if changeSong() then
wait(songLength) -- server cannot detect .Ended()
sound:Destroy() -- garbage collection
end
end
Perhaps due to the recursive part. You probably want to return the result of the recursive call, rather than returning nothing which would cause the loop to instantly run again and call the changeSong function again despite the recursive part.
Something like
else
print("Recursing to find new song...")
return changeSong()
end
May fix the issue.
Another cause may be that TimeLength isn’t instantly updated as sounds take time to load over the network, so you’re setting the songLength to be zero, so your loop doesn’t wait, destroys the sound, and calls the function again. This cycle stops when you load a cached sound where there is no delay is determining the length.