I want to create a sound region that plays a playlist of songs. As in, when the player walks into certain areas of the map, a playlist of songs will play but will not be heard when the player exits that region. Now, in a previous post, another user wrote this code to help making the playlist work inside of a part:
local Sound = game.Workspace:FindFirstChild("Sound") or game.Workspace:WaitForChild("Sound")
local Sounds = Sound:GetChildren()
local CurrentIndex = 1
local Waiting = 5
if Sounds ~= nil and #Sounds > 0 then
for index, instance in ipairs(Sounds) do
if not instance:IsA("Sound") then
table.remove(Sounds, index)
end
end
end
local function PlaySound(sound: Sound)
sound:Play()
sound.Ended:Wait()
wait(Waiting)
end
local function PlayNext()
if #Sounds == 0 then
return
end
if Sounds[CurrentIndex]:IsA("Sound") then
PlaySound(Sounds[CurrentIndex])
CurrentIndex += 1
if CurrentIndex > #Sounds then
CurrentIndex = 1
end
end
end
while true do
PlayNext()
wait(0.1)
end
But now the issue is making this work with the sound region. Changing the rolloff and such that normally works to create a sound region for a single sound has no effect on the playlist sounds and they can be heard throughout the entire game.
I really don’t know what else to do, or what the problem could be and appreciate any suggestions.
I don’t know what you have tried so far, but I would imagine you need a transparent part that covers whatever area of the map you want to have sound. A localscript inside of said part would wait for the player to be in contact with the part, then run the code you gave, stopping the current sound if the player leaves the part. Unless I am mistaken, sounds parented to the Workspace play everywhere regardless of rolloff, so changing it wouldn’t have much effect.
Ok, I’ve created a transparent part that covers the area intended and parented the sounds into a folder in a part.
local part = script.Parent
local soundsFolder = part:FindFirstChild("Sounds")
local playersInRegion = {}
local playerSoundStates = {}
if not soundsFolder then
error("No Sounds folder found in the part")
end
local sounds = soundsFolder:GetChildren()
-- Function to play the playlist
local function playPlaylist(player)
local playerSounds = playerSoundStates[player] or {}
for _, sound in ipairs(sounds) do
local newSound = sound:Clone()
newSound.Parent = player.Character or player.CharacterAdded:Wait()
newSound.TimePosition = playerSounds[sound.Name] or 0
newSound:Play()
playerSounds[sound.Name] = newSound
end
playerSoundStates[player] = playerSounds
end
-- Function to stop the playlist and save state
local function stopPlaylist(player)
local playerSounds = playerSoundStates[player]
if playerSounds then
for soundName, sound in pairs(playerSounds) {
if sound.IsPlaying then
sound:Stop()
playerSounds[soundName] = sound.TimePosition
end
sound:Destroy()
end
end
end
-- Detect when a player enters the region
local function onPlayerEnter(player)
if not playersInRegion[player] then
playersInRegion[player] = true
playPlaylist(player)
end
end
-- Detect when a player exits the region
local function onPlayerExit(player)
if playersInRegion[player] then
playersInRegion[player] = nil
stopPlaylist(player)
end
end
-- Listen for player touch events
part.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
onPlayerEnter(player)
end
end)
part.TouchEnded:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
onPlayerExit(player)
end
end)
this is my new script inside that part. I’m not quite sure why it doesn’t work though.
If you keep the sounds parented to the workspace and just reference them from there, they will be audible anywhere in the map at the same volume. With it being parented to the player, the sound will get quieter if the camera zooms out. With this, just make sure that the script is running on the client so other players can’t hear it and the sounds only play while the player is inside the part. That way you don’t have to clone the sound every time it is played, and you can use sound:Pause() to store where it was stopped. It should resume there assuming you stored which sound the playlist was stopped at.
I forgot to mention the actual reason why it doesn’t work. There are a bunch of errors on lines 30-37 stopping the script from running because of Unknown global ‘sound’ among other reasons. Nothing past that point ever actually runs. Maybe sound was meant to refer to newSound?
Ok, I’ve fixed the issue of this syntax and there are no red lines under any of the script. Right now I’ve parented the sound folder under StarterPlayer, and I’ve turned the script into a LocalScript. Yet, no sounds are played when the player steps inside of the block, and neither does output indicate any possible errors for this. Do you know why this might be?
I can also use the sound:Pause() but I wasn’t sure where to begin to figure out how to store which sound the playlist was stopped at.
Part of the reason nothing is happening is because since it is under StarterPlayer and not any of its sub-folders, it never actually gets sent to the player, so it doesn’t actually exist on the client, though it probably wouldn’t play anyways since the sounds wouldn’t be anywhere in the workspace. Sounds play globally and non-directionally when they are parented to the workspace itself, and they play directionally from the center of an object when parented to any kind of part.
So I’m a bit confused. You suggested I parent the sounds to the player, which I thought I did but I guess I’m not sure I did correctly, as it seems they won’t play if they are not in the workspace. Then, should I parent them to a block in the workspace, or is there a better place to parent them?
, put sounds you want inside the region part you want the sounds to play in
, add script that’ll control sounds
Specfically the script below
local soundRegion = script.Parent --Assumes you have script inside the region
local playlist = {}
local currentTrack = 1
for _,sound in soundRegion do --Checks for all instances that Sounds and adds them to playlist
if sound:IsA("Sound") then
table.insert(soundTable, sound)
end
end
for _,sound in playlist do -- Creates a function for all the sounds
sound.Ended:Connect(function() -- When a track ends moves onto next track, or the beginning of track if at the last traack
if currentTrack == #playlist then
currentTrack = 1
else
currentTrack += 1
end
task.wait(4) -- transition to next sound after 4 seconds
playlist[currentTrack]:Play()
end)
end
Downsides
Tracks don’t pause, even if no players are near or in the region
All the players will be hearing the same soundtrack
Also, I suggest you find SoundService (located somewhere near the bottom of explorer), and enable VolumetricAudio, it makes it better to hear the sounds I guess
More info on Volumetric Audio
if you have error you fix them, I didn’t have studio up when typing this and my hands are cold