Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

What can I do to make this work?

Asked by 8 years ago

Hello!

I am trying to make a music system that pulls songs from a table. I want it to play in a random order, and I want all the songs to play before it lets others play again. Despite my best efforts, I just cant seem to make it work. It works alright in studio, but when I publish it it doesn't want to work in game.

Thank you for your help!

local Songs = {309109778,304029790,243372213,417500483,281929968}
-- Paste the ID of the song, seperated by commas.

local Queue = {unpack(Songs)}

local Speaker = workspace.Sound

while wait(1) do
    if #Queue > 1 then
        if Speaker.IsPlaying == false then
        wait(5)
        local Track = math.random(#Queue)
        local CurrentSong = Queue[Track]
        print(CurrentSong)
        Speaker:Stop()
        Speaker.SoundId = 'http://www.roblox.com/asset/?id='..CurrentSong
        Speaker:Play()
        table.remove(Queue,Track)
        wait(Speaker.TimeLength+.1)
        Speaker:Stop()
    else
        Queue = {unpack(Songs)}
        wait(.1)
    end 

    end
end
0
the problem is that you can't get the timelength of the song on the serverside. use a songended event. LostPast 253 — 8y
0
Perfect, thank you! ninjaflakes 5 — 8y

2 answers

Log in to vote
2
Answered by 8 years ago

Method

The way I'd go about doing this, would be to create a function that creates a new table, with all the same keys and values to the original song list. You could just randomize the order of the initial song list, though if you plan to use it for anything else and the order matters, you're going to want to create a new table for it.

This is also a great opportunity to take advantage of the wait method you can call on events, to suspend the thread until being resumed again. We can use this method on the Ended event of the Sound object, and it's very well compact. I'll go over all of this in the explanation below.

Starting off

First, let's add the variables and create the function:

local Songs = {309109778,304029790,243372213,417500483,281929968}
local Speaker = workspace:WaitForChild("Sound") -- I'd recommend using WaitForChild for this.

-- We'll call the function 'PlayRandomSounds'
local function PlayRandomSounds()

end

Next, we need to create a copy of the table (just like you did with your "Queue" table). This will allow us to select and remove random elements from the table, without effecting the original one:

-- Assuming everything from above is still defined
local function PlayRandomSounds()

    -- Private copy of "Songs"
    local Songs = {unpack(Songs)}

end

Now for choosing random songs, we're going to use a for loop to iterate the copy of the table we just made. As the loop is traversing through the table, it will select random elements along with removing them (to prevent selecting the same random song twice).

-- Assuming everything from above is still defined
local function PlayRandomSounds()
    local Songs = {unpack(Songs)}

    -- Iterate the copied table
    for i = 1,#Songs do

        -- Get, while also removing the randomly selected element
        -- since table.remove returns the element it removed, and we
        -- are indeed working with arrays, this is valid.
        local selected = table.remove(Songs,math.random(#Songs))

        -- Set the SoundId and play it
        Speaker.SoundId = selected
        Speaker:Play()

        -- And finally, use the wait method for the Ended event.
        -- This will make it so it won't play the next song until the current one
        -- has ended.
        Speaker.Ended:wait()

    -- End the for loop
    end

-- End the function
end

So with that covering everything I talked about initially, and applying this example, the final result should look like this:

local Songs = {309109778,304029790,243372213,417500483,281929968}
local Speaker = workspace:WaitForChild("Sound") -- I'd recommend using WaitForChild for this.

-- We'll call the function 'PlayRandomSounds'
local function PlayRandomSounds()
    local Songs = {unpack(Songs)}

    -- Iterate the copied table
    for i = 1,#Songs do

        -- Get, while also removing the randomly selected element
        -- since table.remove returns the element it removed, and we
        -- are indeed working with arrays, this is valid.
        local selected = table.remove(Songs,math.random(#Songs))

        -- Set the SoundId and play it
        Speaker.SoundId = selected
        Speaker:Play()

        -- And finally, use the wait method for the Ended event.
        -- This will make it so it won't play the next song until the current one
        -- has ended.
        Speaker.Ended:wait()

    -- End the for loop
    end

-- End the function
end

Hope this helped, if you have any questions, just let me know.

Ad
Log in to vote
0
Answered by
Link150 1355 Badge of Merit Moderation Voter
8 years ago

Here's how I did it, with detailed explanations:



local songs = { 309109778, 304029790, 243372213, 417500483, 281929968 } local queue local function playNextSong() -- If the queue doesn't exist or is empty, retrieve the songs' assetIDs -- from the songs list. if not queue or #queue == 0 then queue = { unpack(songs) } end -- Search script's children for a Sound object or create a new one -- if inexistant. local sound = script:findFirstChild("Sound") or Instance.new("Sound", script) local index = math.random(1, #queue) -- Get a random element index from the queue. -- Retrieve the assetID of the music from the queue using the index. sound.SoundId = "http://www.roblox.com/asset/?id=" .. queue[index] -- Play the Sound object and wait until the sound.Stopped event is called. sound:Play() sound.Stopped:wait() -- Remove the song from the queue using it's index. table.remove(queue, index) end do -- Shuffle the songs. If we don't do that, the numbers returned -- by the random number generator might not be truly random. math.randomseed(tick()) -- -- See this for more informations: -- http://wiki.roblox.com/index.php?title=Random_numbers -- -- Note: this might not work in Roblox Studio. It didn't -- really work during my testing, anyway. while true do playNextSong() wait(5) end end

Answer this question