How to change a property if name matches criteria

Hi all,

I am trying to add a mute button that will mute anything in the Workspace that is a sound with the name ‘JinglePlayerSound’. It worked fine until I added a second sound with this name into the workspace, but the moment I remove the and sound.Name == "JinglePlayerSound" it works again. I would do this however I have other sounds that I don’t want to be muted when this button is pressed, so I need it to check the name matches my criteria.

local active = true

script.Parent.MouseButton1Click:Connect(function()
	
	for _, sound in ipairs(game.Workspace:GetDescendants()) do 
		if sound:IsA("Sound") and sound.Name == "JinglePlayerSound" then 

			if active == true then
				active = false
				sound.Volume = 0
				script.Parent.ImageColor3 = Color3.fromRGB(181, 0, 3)
				script.Parent.TextLabel.Text = "Off"

			else
				active = true
				sound.Volume = 4
				script.Parent.ImageColor3 = Color3.fromRGB(53, 197, 1)
				script.Parent.TextLabel.Text = "On"
			end
		end			
	end
end)

Hopefully somebody may be able to help, thanks :))

1 Like

It will only reference the first item you have with that name.
You need an array (Tables | Roblox Creator Documentation) using pairs or ipairs to search through a table of parts in a folder or in a model and check to see if it has the name ‘JinglePlayerSound’.

Edit I really need to read through your script before I say stupid stuff like my post.

1 Like

Thanks. Any idea on how to do this, as i’m not entirely sure i’d get it right. I would love to put them all in one folder but unfortunately they are in various groups across the workspace, hence the fact I got descendants of the workspace. Would your idea still work with this?

Thanks for the help too :))

Its because of your active variable, once you set it false after the first loop cycle, it will run the else statement in the second loop cycle

1 Like

Thanks, what could I do instead of the active function to make it run the same?

local active = true

script.Parent.MouseButton1Click:Connect(function()
	
	for _, sound in ipairs(game.Workspace:GetDescendants()) do 
		if sound:IsA("Sound") and sound.Name == "JinglePlayerSound" then 

			if active == true then
				sound.Volume = 0
				script.Parent.ImageColor3 = Color3.fromRGB(181, 0, 3)
				script.Parent.TextLabel.Text = "Off"
			else
				sound.Volume = 4
				script.Parent.ImageColor3 = Color3.fromRGB(53, 197, 1)
				script.Parent.TextLabel.Text = "On"
			end
		end			
	end

    active = not active
    --[[
    if you don't understand the active = not active then you can also do this
    if active then
        active = false
    else
        active = true
    end
    --]]
end)

Something to also keep in mind is that your using getdescendants(), depending on the game if you have a lot of objects in workspace then clicking the button can potentially freeze the player screen for X seconds. I recommand using soundgroups or you can have a table of all the sounds in the game, you can accomplish this by using .ChildAdded or through other methods

2 Likes

Thanks, I do understand the active = not active but thanks for the extra tips!

Would having a table be ‘automated’, so that I don’t have to do anything if I add extra sounds into the game? Also if you can, how would I go about achieving something like that?

script.Parent.MouseButton1Click:Connect(function()
	for _, sound in ipairs(game.Workspace:GetDescendants()) do 
		if sound:IsA("Sound") then
			if sound.Name == "JinglePlayerSound" then 
				sound.Volume = 0
				script.Parent.ImageColor3 = Color3.fromRGB(181, 0, 3)
				script.Parent.TextLabel.Text = "Off"
				task.wait(3)
				sound.Volume = 4
				script.Parent.ImageColor3 = Color3.fromRGB(53, 197, 1)
				script.Parent.TextLabel.Text = "On"
			end
		end
	end
end)

Is this what you’re after?

I guess you could check for when a new Sound instance is added to the storage your monitoring, and deactivate it if the sound meets criteria and sounds are muted.

local active;
local storage = workspace;

storage.DescendantAdded:Connect(function(sound)
    -- check criteria
    if (sound.ClassName == "Sound" and sound.Name == "JinglePlayerSound") then
        -- mute Sound instance
        sound.Volume = 0;
    end
end)

solutions that limited_unique provided I would not recommend,

local Sounds = {} -- [SoundName] = {SoundObj,...}
-- This is a dictionary table with an array table as its value, if this is to complicated you can also just do a single array table with every sound in (similar to getchildren)

workspace.DescendantAdded:Connect(function(Sound)
    if Sound:IsA("Sound") then
        if Sounds[Sound.Name] == nil then
            Sounds[Sound.Name] = {Sound}
        else
             table.insert(Sounds[Sound.Name],Sound)
        end
    end
end)


local active = true

script.Parent.MouseButton1Click:Connect(function()
	local Tbl = Sounds.JinglePlayerSound
	for _, sound in ipairs(Tbl) do 
		if sound:IsA("Sound") and sound.Name == "JinglePlayerSound" then 

			if active == true then
				sound.Volume = 0
				script.Parent.ImageColor3 = Color3.fromRGB(181, 0, 3)
				script.Parent.TextLabel.Text = "Off"
			else
				sound.Volume = 4
				script.Parent.ImageColor3 = Color3.fromRGB(53, 197, 1)
				script.Parent.TextLabel.Text = "On"
			end
		end			
	end

    active = not active
end)

Wrote this real quick so modifications may be needed but this is a good general idea, there are more optimizations you can do to it but I am unfamiliar with your coding ability, so this is a more beginner friendly method, Although I do still recommend checking out soundgroups

Thanks. Soundgroups sound like the perfect solution to this problem, however I also have other things that are toggleable with GUI buttons, such as pointLights. I could use soundgroups for the sounds, but a solution would be needed for the lights one too and as far as I know there’s no such thing as a LightGroup.

Is there anything I need to change in the script above to get it to function as intended? Tried it and it didn’t seem to work… I have a basic knowledge of coding and can write some scripts from the top of my head, but things like this help me to understand more and more. Thanks :))

Yeah that a bit more complicated, if your lights are organized by name

workspace.DescendantAdded:Connect(function(Sound)
    if Sound:IsA("Sound") then
        if Sounds[Sound.Name] == nil then
            Sounds[Sound.Name] = {Sound}
        else
             table.insert(Sounds[Sound.Name],Sound)
        end
    end
end)

Then you just change this to work with lights, like changing the :IsA("Sound") to IsA("PointLight")

If your organizing your lights via models/folders then I would just use getchildren() on those objects whenever you want to do stuff to lights

Really it depends on what your structure is and how you want it

1 Like