Help with table loop

Hi guys, so I have a script where it shuffles through songs I have in a playlist. Everything works perfectly fine, however sometimes the songs loop. For example the song in my list named DeckTheRooftop will play, then it will be followed by RunRunRudolph. However sometimes it will play DeckTheRooftop again, without going to the other songs. Is there a way to make it so that it will shuffle through all of the songs, and it won’t repeat any until all have been played?

Thanks in advance :slightly_smiling_face:

local sounds = {
	[1] = "SantaCanYouHearMe",
	[2] = "UnderneathTheTree",
	[3] = "DeckTheRooftop",
	[4] = "RunRunRudolph",
}

local function ShuffleArray(array)
	local newArray = table.clone(array)

	for i = #newArray, 2, -1 do
		local j = math.random(i)
		newArray[i], newArray[j] = newArray[j], newArray[i]
	end
	return newArray
end

while true do
	for i, soundName in pairs(ShuffleArray(sounds)) do
		local lastSound
		for _, speaker in workspace:WaitForChild("PreShowChristmas"):GetChildren() do
			if speaker:IsA("Part") then
				local sound = speaker:WaitForChild(soundName)
				sound:Play()
				--sound.Volume = 0.2
				lastSound = sound
			end
		end
		lastSound.Ended:Wait()
	end
end
	for i = #newArray, 2, -1 do

You’re starting the for loop at 4 and ending it at 2, meaning only 2 songs are being added to your new array. Then this is being looped in the while true loop.

1 Like

Your array is not being properly iterated.

Code:

local sounds = {
	"SantaCanYouHearMe",
	"UnderneathTheTree",
	"DeckTheRooftop",
	"RunRunRudolph",
}

local function ShuffleArray(array)
	local newArray = table.clone(array)
	
	for i = #newArray, 1, -1 do
		local j = math.random(i)
		newArray[i], newArray[j] = newArray[j], newArray[i]
	end
	
	return newArray
end

while true do
	for i, soundName in pairs(ShuffleArray(sounds)) do
		local lastSound
		
		for _, speaker in workspace:WaitForChild("PreShowChristmas"):GetChildren() do
			if speaker:IsA("Part") then
				local sound = speaker[soundName]
				sound:Play()
				--sound.Volume = 0.2
				lastSound = sound
			end
		end
		
		lastSound.Ended:Wait()
	end
end

Also, if you know an object exists, you can reference the object using Parent[child.Name] or in your case speaker[soundName], instead of using :WaitForChild. It acts like using a dot operator.

For example:

speaker[soundName] -- Let's say soundName is "Dog"

Would be the same as:

speaker.Dog

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.