Adjust playing music's volume

Hello Devs, hope you guys are alright
I have a folder with musics inside of it and with a script that randomly plays one of the musics inside of the folder. I also have a slider that changes the value of a NumberValue for now. So im trying to make it so the volume of the music is adjustable with that slider.

Script that plays the music randomly:

wait(1)
while true do
	local Sounds = script.Parent:GetChildren()
	local RandomIndex = math.random(1,#Sounds)
	local RandomSound = Sounds[RandomIndex]
	RandomSound:Play()
	wait(RandomSound.TimeLength)
end

My idea for now is to make it so the slider changes the currently playing music’s volume instead of the number value but I don’t know how I can do that.

My variable in the Slider right now is

local outputValue = script.Parent.outputValue

The slider script

local mouse = game.Players.LocalPlayer:GetMouse()
local slider = script.Parent
local fill = script.Parent.Fill
local trigger = script.Parent.Trigger
local outputValue = script.Parent.OutputValue
local outputLabel = script.Parent.Label

local maxValue = 1 or 100/100
local startingValue = 0.5 or 50/100

fill.Size = UDim2.fromScale(outputValue.Value,1)
outputLabel.Text = tostring(math.round(outputValue.Value*100))

local tweenService = game:GetService("TweenService")
local tweenStyle = TweenInfo.new(0.25,Enum.EasingStyle.Exponential)

local function UpdateSlider()
	local output = math.clamp(((Vector2.new(mouse.X,mouse.Y)-slider.AbsolutePosition)/slider.AbsoluteSize).X,0,1)
	local outputClamped = startingValue + (output*(maxValue-startingValue))
	
	if outputValue.Value ~= outputClamped then
		tweenService:Create(fill,tweenStyle,{Size = UDim2.fromScale(output,1)}):Play()
		outputValue.Value = outputClamped
		outputLabel.Text = tostring(math.round(outputValue.Value*100))
		print(output)
	end
end

local sliderActive = false

fill:GetPropertyChangedSignal("Size"):Connect(function()
	outputLabel.Text = tostring(math.round(fill.Size.X.Scale*100))
end)

local function ActivateSlider()
	sliderActive = true
	UpdateSlider()
end

trigger.MouseButton1Down:Connect(ActivateSlider)

game:GetService("UserInputService").InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		sliderActive = false
	end
end)

mouse.Move:Connect(function()
	if sliderActive then
		UpdateSlider()
	end
end)

Any help would be appreciated
Thanks

2 Likes

You should be able to just do

wait(1)
while true do
	local Sounds = script.Parent:GetChildren()
	local RandomIndex = math.random(1,#Sounds)
	local RandomSound = Sounds[RandomIndex]
    RandomSound.Volume = tonumber(outputValue.Value) or 1
	RandomSound:Play()
	wait(RandomSound.TimeLength)
end
2 Likes

the script that I provided is the whole script tha randomly plays the musics, its not a part of the slider
My bad for not including the slider, I’m going to do it right now

3 Likes

But if it’s updating the numbervalue, you should just be able to reference it from the script that handles the music, no?

2 Likes

Hm, good idea, I’m gonna try that

2 Likes

I made it so the music script takes the Value of the NumberValue inside of the LocalPlayer’s GUI and puts it as the Volume for the currently playing music. It works when I change the value of the NumberValue before playtesting but doesnt when I change the Value of the slider inside of playtesting.
It looks like the music’s volume needs to constantly check and update the volume

1 Like

Oh yeah, you can just fire a BindableEvent every time you change the volume, and save the current playing music somewhere outside of the while loops scope.


local currentPlayingSong = nil
wait(1)
while true do
	local Sounds = script.Parent:GetChildren()
	local RandomIndex = math.random(1,#Sounds)
	local RandomSound = Sounds[RandomIndex]
    RandomSound.Volume = tonumber(outputValue.Value) or 1
	RandomSound:Play()
    currentPlayingSong = RandomSound
	wait(RandomSound.TimeLength)
end

<BindableEvent>.Event:Connect(function(volume)
    if not currentPlayingSong then return end
    currentPlayingSong.Volume = tonumber(volume) or 1
end)
2 Likes

The NumberValues .Changed event would be much easier to implement, but really instead of using a loop we should set the volume everytime we change the sound value.

A very easy way to do this would be to make a seperate Sound instance and use it to play audio, and with that you can just set its volume whenever you want without using too much performance.

4 Likes

I don’t quite understand what to do here, the Slider’s script and the musics script is different so there is no outputValue variable

2 Likes

instead of using a loop we should set the volume everytime we change the sound value.

The loop for him handles the music switching, not the volume changing, you’re correct about changed

2 Likes

outputValue would be your reference to the volume numbervalue, and you should also use Changed to detect when the player changes volume, and set the currentPlayingSong’s volume to that

3 Likes

You can just use the new UIDragDetectors, right?

local Frame = script.Parent
local DragDetector = Frame.UIDragDetector

local startPos = UDim2.new(0, 0, 0, 0)
local endPos = UDim2.new(0, 572, 0, 0)

local totalDragDistance = (endPos.X.Offset - startPos.X.Offset)

DragDetector.DragContinue:Connect(function()
	
	local currentDragPosition = DragDetector.DragUDim2
	local relativePos = currentDragPosition.X.Offset / totalDragDistance
	relativePos = math.clamp(relativePos, 0, 1)

	--Volume code here.
end)
2 Likes

ohh okay, so something like

local player = game:GetService("Players").PlayerAdded:Wait()
local ouputValue = player.PlayerGui.SettingsMenu.Frame.Music.OutputValue

wait(1)
while true do
	local Sounds = script.Parent:GetChildren()
	local RandomIndex = math.random(1,#Sounds)
	local RandomSound = Sounds[RandomIndex]
	RandomSound:Play()
	RandomSound.Volume = player.PlayerGui.SettingsMenu.Frame.Music.OutputValue.Value
	wait(RandomSound.TimeLength)
	outputValue.Changed:Connect(function()
		RandomSound.Volume = outputValue.Value
	end
end

should work

2 Likes

Take the changed event outside of the while loop and it should be fine

2 Likes

If I do that, then there wont be a RandomSound variable

2 Likes

Hence why i told you to save the currentPlayingSong outside of the while loops scope.

2 Likes

UIDragDetectors are pretty new, so I don’t really think that there will be lots help or tutorials online. But I might try that

2 Likes

I might be stupid, I don’t understand. I cant put the RandomSound outside of the loop.
The first variable inside the loop gets children from the folder with musics
The second variable is randomness i think
The third variable is the music chosen randomly

If I take out the third variable from the loop, then it won’t know what the second variable is since its not in the same “drawer”

2 Likes
local player = game:GetService("Players").PlayerAdded:Wait()
local ouputValue = player.PlayerGui.SettingsMenu.Frame.Music.OutputValue

local currentPlayingSong  = nil
wait(1)
while true do
	local Sounds = script.Parent:GetChildren()
	local RandomIndex = math.random(1,#Sounds)
	local RandomSound = Sounds[RandomIndex]
	RandomSound:Play()
	RandomSound.Volume = player.PlayerGui.SettingsMenu.Frame.Music.OutputValue.Value
    currentPlayingSong = RandomSound
	wait(RandomSound.TimeLength)
end

outputValue.Changed:Connect(function()
	currentPlayingSong.Volume = outputValue.Value
end
1 Like

last line of code, isnt currentPlayingSong nothing? in the variable it’s just nil, and it got changed only in the loop
The volume doesn’t change

1 Like