A bug in my script that I don't know how to fix

So, I made music zones in my game, and a mute system. It was working finely until I discovered this bug.


This is my zone script

local part = script.Parent
local sound = Instance.new("Sound", game.SoundService.Music)
local muted = false
local inzone = false

-- Set the sound properties
sound.Name = "Music"
sound.SoundId = "rbxassetid://1837570261"  -- Replace with your sound asset ID
sound.Volume = 1
sound.Looped = true  -- Set to true if you want the music to loop
sound:Play()

game.ReplicatedStorage.Events.Muted.OnServerEvent:Connect(function()
	if inzone == true then
		sound.Volume = 0
		muted = true
	end
end)

game.ReplicatedStorage.Events.Unmuted.OnServerEvent:Connect(function()
	if inzone == true then
		sound.Volume = 1
		muted = false
	end
end)

-- Table to track players in the zone
local playersInZone = {}

-- Function to play the sound when the part is touched
local function onTouch(other)
	-- Check if the object that touched the part is a player
	local character = other.Parent
	local player = game.Players:GetPlayerFromCharacter(character)

	if player and not playersInZone[player] then
		-- Add player to the table
		playersInZone[player] = true
		inzone = true
		-- Play the sound if it is not already playing
		if muted == false then
			sound.Volume = 1
		end
	end
end

-- Function to stop the sound when the player leaves the part
local function onTouchEnded(other)
	-- Check if the object that left the part is a player
	local character = other.Parent
	local player = game.Players:GetPlayerFromCharacter(character)

	if player and playersInZone[player] then
		-- Remove player from the table
		playersInZone[player] = nil
		inzone = false

		-- Stop the sound if no players are in the zone
		if next(playersInZone) == nil then
			sound.Volume = 0
		end
	end
end

-- Connect the onTouch and onTouchEnded functions to the Touched and TouchEnded events
part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)

And this is my mute script.

local tweenservice = game:GetService("TweenService")
local button = script.Parent
local base = button.Parent
local circle = base.MuteCircle
local start = base.MuteCircleStart
local goal = base.MuteCircleGoal
local muted = false
local timer = 0.15
local events = game:GetService("ReplicatedStorage"):WaitForChild("Events")

if muted then
	circle.Position = start.Position
else
	circle.Position = goal.Position
end

local function toggleAround()
	if muted then
		local info = TweenInfo.new(timer, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)
		local tween = tweenservice:Create(circle, info, {Position = goal.Position})
		tween:Play()
		circle.Position = start.Position
		muted = false
		events.Unmuted:FireServer()
	else
		local info = TweenInfo.new(timer, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)
		local tween = tweenservice:Create(circle, info, {Position = start.Position})
		tween:Play()
		circle.Position = goal.Position
		muted = true
		events.Muted:FireServer()
	end
end

button.Activated:Connect(function()
	toggleAround()
end)

Any help is appreciated!

1 Like

when you unmute/mute the music, it checks if the player is in the zone or not, so nothing happens if you unmute outside of the zone. remove the check and it should work fine.

I don’t understand what your desired behavior is for this system. Normally, a mute UI option is just for that one player to mute the music, but the way you’ve coded things, any player toggling their mute switch affects the server’s sound player, muting or unmuting the sound for all players. All players are able to mute or unmute the server, as long as at least one player is in the zone. I can’t imagine why you’d want that.

If what you want is just for each player to hear the music when they are unmuted and standing within the circle, then that would be done all client-side, so that each player’s mute option is for them only. There’s no reason to change the sound.Volume property on the server unless it’s your intention for it to change instantly for all players. Just have the sound looping and playing on the server, with Volume = 0, and change it locally for each player as they enter or leave the area, and when they toggle their mute switch.

If the goal was for the sound to player for everyone, whenever there is at least one player in the area, then you could keep your current inzone mechanic, but you probably still want mute/unmute to be per player, right?

2 Likes

Well, the script was from a youtube video. So I don’t know what it does.

Without the check, if I unmute outside the zone, the music would play.

but the music is supposed to play only if you’re in the zone, correct?

Yes. The music should play in the zone.

extended because character limit

you shouldn’t be setting the volume to 0 or 1 to pause/play the music, you should be using sound:Pause() and sound:Resume()

if you want a better and easier zone music system, i enjoy this one. i haven’t tried it, but it would be pretty easy to add music toggle support. i can show you an example script if you like.

Well, I don’t use any free models in my game whatsoever. But I guess I’ll try it.

1 Like

you said it was from a youtube video, and thats… pretty similar to a free model

1 Like

Agreed. If you skim through a tutorial to just copy the code without learning how it works, then there is no meaningful difference.

1 Like

So I tried it out. It seems that it plays on touch I want mine to make it so that if you’re in the zone, it plays the music. And when you get out of the zone, it stops the music.

I kinda learned how it worked just by looking at the code though.

oh right, i forgot about that feature. it would be very simple to make your own script for this, using Region3, judging by your Programmer flair…

Roblox tutorials are also often from random noobs who also have no idea what they are doing. So there is a better than average chance you were copying code that doesn’t work or works in Studio Play Solo but totally doesn’t work in a live, multiplayer game.

What you probably want is to do this whole system in a LocalScript, where on each player’s client you track when their character enters or leaves a zone, and when they toggle Mute. Any time either of these factors changes, you update the sound like so:

sound.Volume = if (inzone and unmuted) then 1 else 0

When you call this from LocalScript, it only changes the volume on their client, it does not mute the sound for other players. Because your sound is in SoundService, you want it to have Volume = 0 on the server, always. If you set it non-zero on the Server, suddenly all players will hear it, no matter where they are, as it will stomp over their local value for the property and these sounds are global.

2 Likes

One second to understand this, do you want music to still play in the zone when the mute music option is on?

Hey, cupcake_BoyzCary.

I think that it would be best if rather than looking for regions inside of a designated circle, you can instead, mark all Music Instances with a special tag and then using CollectionService you can mute them all by changing their Volume.

No. I don’t want music to play in the zone when mute is on.

You could just make the songs always play and stop no matter the value of mute music. Then make mute music simply change the volumes of the audios.