The song GUI doesn’t update what song is playing for that server as well, and also It’s a normal script, not a local script.
So you want to have a system that loops through the songs in a folder and plays them?
Yes, throughout the server it plays on the server, so when a player joins a game, it hears that same song everyone else is listening to, and the gui changes to that song as well
Can you guide me on what to do?
Oh yes sorry, I got distracted. However, note, that I’m not going to be doing it so that everybody hears the same song, it’s a little complex for your current skill (hopefully one day you’ll be able to).
So the first thing you need to do is make a table, which is basically a big lump of organized values under 1 variable. To do that, all we have to do is
--Note, this script is a local script inside StarterPlayerScripts
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren() --We use "WaitForChild" so that way the game doesn't bug out
When we say :GetChildren() we’re saying get all the children of the folder “songs.”
Here is an example of what a parent-child relationship looks like in the explorer:
Next what we want to do is loop through the table that we set previously (SongsFolder) using a for loop. Assuming i stands for “index” and v stands for “value,”
for i, v in pairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
wait(v.TimeLength) --Wait for it to end
end
However, since this loop will stop repeating itself after it has gone through all the songs, what we have to do is put that loop inside a while loop, like so:
while wait(1) do
for i, v in pairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
wait(v.TimeLength) --Wait for it to end
end
end
This will make it so that even after it loops through the whole folder, it will repeat again; therefore making it so they will never stop playing.
Our final code should look like this.
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
--The above is here just to make sure the songs don't start playing too early (before loading)
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()
while wait(1) do
for i, v in pairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
wait(v.TimeLength) --Wait for it to end
end
end
A noteworthy thing, using wait() can introduce unexpected delays and such. It’s probably better to use Sound | Roblox Creator Documentation to register when the sound ended, and with the new task library, wait() has been improved upon, mostly eliminating the throttling issues with wait().
Another thing to note, typically in game music flows better with a small wait in-between each song.
One other thing to note, pairs() doesn’t run things in a particular order, so if you want it to be consistent, you can use ipairs().
Last note, Players | Roblox Creator Documentation only works in LocalScripts, and as noted here:
With all these tweaks, this:
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
--The above is here just to make sure the songs don't start playing too early (before loading)
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()
while wait(1) do
for i, v in pairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
wait(v.TimeLength) --Wait for it to end
end
end
would become this:
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()
while true do
for i, v in ipairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
v.Ended:Wait() --Wait for it to end
task.wait(3) -- 3 second delay between songs, optional
end
end
k I got it working but the only thing I need help on, is how do I make it so the GUI changes with the song name in starter GUI, whenever a player joins and is in game.
Is the script playing the songs a local script or a server script?
Server script, as noted in post #2
It’s just playing in workspace in a folder, with that script I’ve mentioned in the folder and that’s it.
What you can do is use RemoteEvent:FireAllClients()
and send the song name through that. Put a remote event in Replicated Storage named “SongNameRE,” and assuming you’re using @Inconcludable’s script, you’d change it to:
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()
while true do
for i, v in ipairs(SongsFolder) do --Go through the songs folder
v:Play() --Play the song
game.ReplicatedStorage.SongNameRE:FireAllClients(v.Name)
v.Ended:Wait() --Wait for it to end
task.wait(3) -- 3 second delay between songs, optional
end
end
And then as a local script (in StarterPlayerScripts), you’d put
game.ReplicatedStorage.SongNameRE.OnClientEvent:Connect(function(SongName)
--Set the player's screen gui text to SongName
end
Make sure you set the player variable too, preferrably above the event listener.
It’s just a normal script, and it works… But the only thing I need to do now is so the starter GUI matches the text as the song is currently playing, and in the workspace with my songs folder, and it has a script in that exact folder just looks like this like I’ve mentioned…
while true do
local l__Songs__1 = game.Workspace.Songs;
wait(0.1);
l__Songs__1.WalkMeHome.Playing = false;
l__Songs__1.SubZero.Playing = true;
wait(120.084);
l__Songs__1.SubZero.Playing = false;
l__Songs__1.SlowMotion.Playing = true;
wait(120.216);
l__Songs__1.SlowMotion.Playing = false;
l__Songs__1.JustForTheNight.Playing = true;
wait(80.169);
l__Songs__1.JustForTheNight.Playing = false;
l__Songs__1.JocelynFlores.Playing = true;
wait(117.472);
l__Songs__1.JocelynFlores.Playing = false;
l__Songs__1.Hotel.Playing = true;
wait(327.523);
l__Songs__1.Hotel.Playing = false;
l__Songs__1.NoTearsLeftToCry.Playing = true;
wait(208.143);
l__Songs__1.NoTearsLeftToCry.Playing = false;
l__Songs__1.UpLikeAnInsomniac.Playing = true;
wait(87.536);
l__Songs__1.UpLikeAnInsomniac.Playing = false;
l__Songs__1.JocoleynFlores.Playing = true;
wait(117.472);
l__Songs__1.JocoleynFlores.Playing = false;
l__Songs__1.xSupply.Playing = true;
wait(84.816);
l__Songs__1.xSupply.Playing = false;
l__Songs__1.LensV2.Playing = true;
wait(100);
l__Songs__1.LensV2.Playing = false;
l__Songs__1.AllTheWayUp.Playing = true;
wait(195.291);
l__Songs__1.AllTheWayUp.Playing = false;
l__Songs__1.GetYou.Playing = true;
wait(277.75999999999993);
l__Songs__1.GetYou.Playing = false;
l__Songs__1.HowToSaveALife.Playing = true;
wait(76.79999999999971);
l__Songs__1.HowToSaveALife.Playing = false;
l__Songs__1.BarbieDrip.Playing = true;
wait(108.14799999999961);
l__Songs__1.BarbieDrip.Playing = false;
end;
All I need to do is just make sure StarterGUI matches that name of the song whenever someone joins the game, the GUI auto updates to that exact song playing.
(Note that this will make it so that players who have recently joined won’t have the music playing, as the server still thinks no songs are playing)
it works in game? Whenever I rejoin or leave and go back, still plays the servers song.
Hmm, this makes it a bit more complex. A possible solution is to store the song in an ObjectValue | Roblox Creator Documentation every time the song changes. With modifications to the previous code I provided, it would look like this:
local SongsFolder = game.Workspace:WaitForChild(“Songs”):GetChildren()
while true do
for i, v in ipairs(SongsFolder) do --Go through the songs folder
if v:IsA("Sound") then
SongsFolder.SongPlaying.Value = v
-- You will need to create an object value in "SongsFolder" named "SongPlaying"
v:Play() --Play the song
v.Ended:Wait() --Wait for it to end
task.wait(3) -- 3 second delay between songs, optional
end
end
end
To get the name of the song on the client, you can bind an event to the ObjectValue changing. Here’s an example:
local SongFolder = workspace:WaitForChild("SongsFolder", 30)
if not SongFolder then error("Unable to locate song folder!") end
local SongPlayingValue = SongFolder:FindFirstChild("SongPlaying")
if not SongPlayingValue then error("Unable to locate song ObjectValue!") end
--// Use this space to change the Playing song name/TextLabel, as the
--// .Changed event will not fire since a song is already playing
SongPlayingValue.Changed:Connect(function(song)
if song then
--Use this space to change the Playing song name/TextLabel
end
end)
If you have any issues with this, let me know.
I’m just gonna use a string value, and update it everytime when the song changes and change to that name.
How do I change the string value in a script?
You set the StringValue | Roblox Creator Documentation property to whatever the string is, like:
StringValue.Value = "This is a string"
or
StringValue.Value = ExampleProperty.Name
I have it like this
wait(0.1);
l__Songs__1.WalkMeHome.Playing = false;
currentTrack.Value = Name
Did you ever define what the “Name” variable was?