SFX Volume GUI Sound Effects Functionality

Hey everyone, so recently I’ve been attempting to make a SFX ON/OFF button. This button works with actions and sword sound effects. But for whatever reason, sound effects inside the GUI, which are located inside buttons, don’t go back to their original volume after I set them to off. In fact, they stay at 0 volume forever after I click off. Here are the 2 scripts I have that work well. The first is for all sounds while the second focuses on swords. I’ve attached some additional picture for help.

Disclaimer: I didn’t do a lot of this scripting as I found it too hard for my level, so this was mainly done by ChatGPT with my modifications and tweaking of variables and functions.

local button = script.Parent
local debounce = false
local isSFXOn = true -- Keep track of SFX state
local allSounds = {} -- Store sounds in table

-- Save the original volume and mute the sound
local function resetVolume(sound)
	if sound.Volume ~= 0 then -- Do not save volume when it is set to 0
		allSounds[sound][1] = sound.Volume -- Save volume to index 1 of table
		sound.Volume = 0
	end
end

-- Check if the object is a sound and handle it accordingly
local function checkInstance(object)
	pcall(function()
		if object:IsA("Sound") and object.TimeLength <= 6 then
			local parent = object.Parent
			while parent do
				if parent:IsA("Tool") then
					return
				end
				parent = parent.Parent
			end

			if not allSounds[object] then 
				allSounds[object] = {} -- Create table for sound
				allSounds[object][1] = object.Volume -- Save original volume
				allSounds[object][2] = object:GetPropertyChangedSignal("Volume"):Connect(function()
					if isSFXOn then
						allSounds[object][1] = object.Volume -- Update original volume when SFX is on
					else
						object.Volume = 0 -- Set volume to 0 when SFX is off
					end
				end)
			end
			if not isSFXOn then
				object.Volume = 0 -- Set volume to 0 if SFX is off
			end
		end
	end)
end

local function checkToolSounds(tool)
	if tool:IsA("Tool") and tool:FindFirstChild("Handle") then
		for _, child in ipairs(tool.Handle:GetChildren()) do
			if child:IsA("Sound") then
				checkInstance(child)
			end
		end
	end
end

local function toggleSFX()
	if isSFXOn then
		for sound, _ in pairs(allSounds) do
			sound.Volume = 0
		end
	else
		for sound, data in pairs(allSounds) do
			sound.Volume = data[1] or 1 -- Restore to original volume or default to 1
		end
	end
	isSFXOn = not isSFXOn
end

button.MouseButton1Up:Connect(function()
	if not debounce then
		debounce = true

		
		toggleSFX()

		
		wait(0.2)
		debounce = false
	end
end)

for _, object in ipairs(game:GetDescendants()) do 
	checkInstance(object)
end

local swords = {"ClassicSword", "FlameSword", "GuardianSword"}
for _, swordName in ipairs(swords) do
	local sword = game.ReplicatedStorage:FindFirstChild(swordName)
	if sword then
		checkToolSounds(sword)
	end
end


local soundAdded = game.DescendantAdded:Connect(function(object)
	checkInstance(object)
	if object:IsA("Tool") then
		checkToolSounds(object)
	end
end)

local toolAdded = game.ChildAdded:Connect(function(child)
	checkToolSounds(child)
end)

For swords:

local button = script.Parent
local debounce = false
local isSFXOn = true -- Keep track of SFX state
local allSounds = {} -- Store sounds in table

local swords = {"ClassicSword", "FlameSword", "GuardianSword"}

-- Save the original volume and mute the sound
local function saveAndMuteSound(sound)
	if sound.Volume ~= 0 then
		allSounds[sound] = sound.Volume
		sound.Volume = 0
	end
end

-- Restore the sound volume from saved data
local function restoreSoundVolume(sound)
	if allSounds[sound] then
		sound.Volume = allSounds[sound]
	else
		sound.Volume = 1 -- Default volume if not saved
	end
end

-- Check if the object is a sound and handle it accordingly
local function checkInstance(object)
	pcall(function()
		if object:IsA("Sound") and object.TimeLength <= 6 then
			if not allSounds[object] then -- Ensure the sound is not already in the table
				allSounds[object] = object.Volume -- Save original volume
			end
			if not isSFXOn then
				object.Volume = 0 -- Set volume to 0 if SFX is off
			end
		end
	end)
end

-- Handle sounds inside sword tools
local function handleSwordSounds(sword)
	if sword:IsA("Tool") and sword:FindFirstChild("Handle") then
		for _, child in ipairs(sword.Handle:GetChildren()) do
			if child:IsA("Sound") then
				checkInstance(child)
			end
		end
	end
end

local function toggleSFX()
	if isSFXOn then
		for sound, _ in pairs(allSounds) do
			sound.Volume = 0
		end
	else
		for sound, _ in pairs(allSounds) do
			restoreSoundVolume(sound)
		end
	end
	isSFXOn = not isSFXOn
end

button.MouseButton1Up:Connect(function()
	if not debounce then
		debounce = true

		toggleSFX()

		
		wait(0.2)
		debounce = false
	end
end)


for _, object in ipairs(game:GetDescendants()) do
	checkInstance(object)
end

for _, swordName in ipairs(swords) do
	local sword = game.ReplicatedStorage:FindFirstChild(swordName)
	if sword then
		handleSwordSounds(sword)
	end
end


local soundAdded = game.DescendantAdded:Connect(function(object)
	checkInstance(object)
	if object:IsA("Tool") then
		handleSwordSounds(object)
	end
end)


local toolAdded = game.ChildAdded:Connect(function(child)
	handleSwordSounds(child)
end)

image

image

image