I am trying to make a soudtrack playlist for my game but i cannot seem to get more than one song to play in a row.
here is my current code:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks")
local songs = {}
function playSong(song)
Soundtracks[song]:Play()
end
function findSongs()
for i,v in pairs(Soundtracks:GetChildren()) do
table.insert(songs, v.Name)
end
end
function getRandomSong()
local i = math.random(1, #songs)
return songs[i]
end
findSongs()
wait(1)
local i = getRandomSong()
playSong(i)
I have not tested this code but would this maybe work?
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks"):GetChildren()
function getRandomSong()
return Soundtracks[math.random(1, #songs)]
end
local song = getRandomSong()
song:Play()
song.Ended:Connect(function()
song = getRandomSong()
song:Play()
end)
The issue with the provided code is that it doesn’t loop. The functions work perfectly (although there are some things that can be improved upon), but as soon as the first song ends… Silence.
Solution
Okay, how do we fix this? It’s actually quite simple! The sound class comes with a couple of life-savers too, such as the .Ended event which fires upon the sound ending.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks"):GetChildren()
--:GetChildren() returns an array, no need to index it!
function getRandomSong()
local i = math.random(1, #Soundtracks)
return Soundtracks[i]
end
function playSong()
local Song = getRandomSong() --Get a new song.
Song:Play() --Start the tunes!
Song.Ended:Wait() --Wait for the song to end
playSong() --Reinitialize the function.
end
playSong()
A couple of notes:
:GetChildren() returns an array, making the entire findSongs() business unnecessary.
Recursion! The playSong() function will now call itself when it finishes a song, which resolves the issue with no new songs playing.
I’ve heard some bad stuff about wait() and that specifically using it without any parameters can cause problems with some kind of back-end execution stuff. I like the recursion but isn’t it better to use
I believe you’re confusing the global function with the wait used with events. Wait:() in the context of an event is ideal, it pauses the thread until the event fires.
Recursion can be an issue when a function calls itself a lot and within a short time frame. The example you provided does the same thing as what I provided - the event will still (although implicitly) call itself, creating recursion.
I suggest u making a “Counter” variable to keep track of your audios. U can easily loop through the script get all the songs table insert them then do Sounds[Count]:Play() wait till it ends and update the counter