So I made a script (not local) that plays random music for a music zone. But I found an error when I played the game and it kept spamming the same thing.
local sound = script.Parent.Ambiences.Ambience
local rs = game:GetService("RunService")
local music = {
Track1 = {
Name = "Chilled Relaxation",
ID = 1839363112
},
Track2 = {
Name = "Busy Vibes",
ID = 1836393138
},
Track3 = {
Name = "Soft Sounds",
ID = 1840384233
},
Track4 = {
Name = "Lo Fi Bay",
ID = 9040313420
}
}
local function getRandomTrack()
local tracks = music
local track = tracks[math.random(1, #tracks)]
return track
end
rs.Heartbeat:Connect(function()
local randomTrack = getRandomTrack()
sound.SoundId = "rbxassetid://"..randomTrack.ID
sound:Play()
sound.Ended:Wait()
end)
You can’t get the number of elements from dictionary table using #. To solve the problem, you can simply remove the keys in music (Track1, Track2, Track3, Track4)
This is the revised code:
local sound = script.Parent.Ambiences.Ambience
local rs = game:GetService("RunService")
local music = {
{
Name = "Chilled Relaxation",
ID = 1839363112
},
{
Name = "Busy Vibes",
ID = 1836393138
},
{
Name = "Soft Sounds",
ID = 1840384233
},
{
Name = "Lo Fi Bay",
ID = 9040313420
}
}
local function getRandomTrack()
local track = music[math.random(1, #music)]
return track
end
rs.Heartbeat:Connect(function()
local randomTrack = getRandomTrack()
sound.SoundId = "rbxassetid://"..randomTrack.ID
sound:Play()
sound.Ended:Wait()
end)
The error you’re getting is due to .lua not being able to get the length of a dictionary table (returning 0). You can use @Crynoxia_1’s method or check this post if you still want to use a dictionary table as your method.
because you are assigning a new id to the sound and playing it every heartbeat signal. instead you can just do that:
--!native
--!optimize 2
--!nocheck
local sound = script.Parent.Ambiences.Ambience
local music = {
{
Name = "Chilled Relaxation",
ID = 1839363112
},
{
Name = "Busy Vibes",
ID = 1836393138
},
{
Name = "Soft Sounds",
ID = 1840384233
},
{
Name = "Lo Fi Bay",
ID = 9040313420
}
}
local function getRandomTrack()
return music[math.random(1, #music)]
end
while true do
sound.SoundId = "rbxassetid://"..getRandomTrack().ID
sound:Play()
sound.Ended:Wait()
end
Heartbeat doesn’t wait for any intervals (unless you use debounce which I don’t recommend). So the Ended function doesn’t do any effect.
Since you don’t want to use any while true loops, I recommend making a function that loops through itself.
local function pSound()
local randomTrack = getRandomTrack()
warn(randomTrack)
sound.SoundId = "rbxassetid://"..randomTrack.ID
sound:Play()
sound.Ended:Wait()
pSound()
end
pSound()
Something that I also recommend you doing (since Roblox has this “Issue” for a long time) is to also make a line before the Play() and add sound.TimePosition = 0, that way the music doesn’t stars at its middle or end.