Tool sound isnt server sided?

So I thought my tool could be heard by other players when you use it, but turns out that isn’t the case…?

local swinganimationid = 9671188351


repeat wait() until game.Players.LocalPlayer.Character
local lp = game.Players.LocalPlayer
local sp = script.Parent
local debounce = true
local sound = script.Parent.Sound1
local sound2 = script.Parent.Sound2

local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://" .. swinganimationid
local swingtrack = lp.Character.Humanoid:LoadAnimation(anim)

sp.Activated:connect(function()
	if debounce == true then
		debounce = false
		swingtrack:Play()
		sound:Play()
		sound2:Play()
		wait(swingtrack.Length)
		sound2:Stop()
		sound:Stop()
		debounce = true
	end
end)
1 Like

If it’s a local script then yes, other players won’t be able to hear the sounds.

Okay… but like… how do I fix it

Sounds you want heard by the server need to be moved to the workspace, or SoundService folder… and their location redefined in your script.

Didn’t really work, ah this is kinda weird

If you want the entire server to hear the sound, you’ll need to use a remote event.

Alternatively(not best choice) would be to turn that script into a server script.

SoundService has a property called RespectFilteringEnabled. When the property is true, any sound played locally will be replicated to the server.

1 Like

Just switch the script to be server sided. You would have to change this line

local lp = game.Players.LocalPlayer

to this

local lp = script.Parent.Parent --This is if the script is inside the tool and not the handle.  If the script is inside the handle do this.
local lp = script.Parent.Parent.Parent
1 Like

image

local swinganimationid = 9671188351
local player = game.Players.LocalPlayer
repeat wait() until player.Character and player.Character.Parent
local hum = player.Character.Humanoid
local debounce = true
local sound = script.Parent.Handle.Sound1
local sound2 = script.Parent.Handle.Sound2
local rs = game:GetService("ReplicatedStorage")
local remoteEvent = rs:WaitForChild("RemoteEvent")

local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://" .. swinganimationid
local swingtrack = hum:LoadAnimation(anim)

script.Parent.Activated:connect(function()
	if debounce == true then
		debounce = false
		swingtrack:Play()
		sound:Play()
		sound2:Play()
		wait(swingtrack.Length)
		sound2:Stop()
		sound:Stop()
		debounce = true
	end
	remoteEvent:FireServer()
end)

I looked up how to do it with a remoteevent and I have no idea what to put in the server script. :frowning: This is so hard

1 Like

Assuming the player is holding the tool when the sound plays:
Use remoteEvent:FireServer() to send data to the server, everything in between the “()” gets sent, these are the ‘args’.

Since we are sending a sound to the server we place the sound object reference inside the args. This in your case would mean using remoteEvent:FireServer(sound) and remoteEvent:FireServer(sound2).

After we send the info from the client, we need to receive it on the server. To do this we use:

remoteEvent.OnServerEvent:Connect(function(plr, sound) -- notice that argument 1 is player
sound:Play()
end)

The above code only works in a server script.

Now lets tie this all together:

Client:

local tool = script.Parent
local soundEvent = game.ReplicatedStorage.SoundEvent

tool.Equipped:Connect(function()
	print("Activate!")
	soundEvent:FireServer(tool.Sound)
end)

Server:

local REP = game:GetService("ReplicatedStorage")

REP.SoundEvent.OnServerEvent:Connect(function(plr, sound)
	sound:Play()
	print("Sound played on server!")
end)

Explorer Layout:
image

This is my tested, working example. Your tool will need different object references because the sound is located elsewhere.

Remotes were also complicated for me when I began learning Lua, so I hope this helps!

If you still have questions or need help, feel free to ask.:slight_smile:

I mean, I’ve gotten events working in other scenarios, its like, the script requires the player to use an animation and while they’re using it the sound stops when the animation stops since the audio length is a tad longer. So this is just super tiring and I’ve been at it for 5 hours. I did not think wanting to make a simple emote with working sound would be this stressful and tedious.

1 Like

Could you share with me the code that’s causing you trouble?

I’m sure I could find a solution to the problem you described if I knew the code setup. It sounds like you need to separate the sound code from the animation code, most likely through spawn(function() or sound.Ended:Connect(function().

Yeah, but I’ve shared the code twice :confused:

1 Like

Oh, my apologies I didn’t recognize that you were talking about the above code.

Why do you decide to :Stop() the sounds after the animation ends? Don’t the sounds automatically stop when they’ve ended?

It’s an applaud emote, and the clapping audio goes on longer than the animation which looks and sounds weird. But if it wasn’t said before, the animation locally works fine but I just need the audio to be heard server-side. As you and a few others already said, events should do it. But when I separate the sound separately, it does the problematic thing as I just mentioned, it goes on longer than the animation because the sound I picked out is by Roblox.

1 Like

you hage to make it a serverscript somehow sorry

You could move the animation over to the server, and seeing as it is just an emote the delay won’t be much of an issue for the player.

Server:
Just create the animation on the server and load it onto the player when they call it.

Server pt.2:
When you receive the event on the server just do:

local track = plr.Character.Humanoid:LoadAnimation(anim)
track:Play()

You can then implement your timer on the server and leave all of the player input on the client. If my explanation is a bit confusing I can draft up some working code for you.

Not really because when tools are equipped they are moved into the player character which is in the workspace

As aforementioned, for sounds to be heard by everyone, anything related needs to be done on the server. That also applies to stopping the sound; this can all be handled with one remote event.

Insert a RemoteEvent inside of the tool, I’d just call it ‘SoundEvent’ personally.

Then insert a ServerScript alongside the LocalScript inside of the tool:

local tool = script.Parent
local handle = tool:WaitForChild("Handle")
local sound1 = handle:WaitForChild("Sound1")
local sound2 = handle:WaitForChild("Sound2") -- assuming the sounds are in the handle

local soundEvent = tool:WaitForChild("SoundEvent")

soundEvent.OnServerEvent:Connect(function(plr, sound, toggleType)
    if plr.Name ~= tool.Parent.Name then return end -- prevents event manipulation
    
    if toggleType == "play" then
        sound:Play()
    else
        sound:Stop()
    end
end)

Now we just need to adjust the LocalScript:

local swinganimationid = 9671188351


repeat wait() until game.Players.LocalPlayer.Character
local lp = game.Players.LocalPlayer
local sp = script.Parent
local handle = sp:WaitForChild("Handle")
local debounce = true
local sound =  handle:WaitForChild("Sound1")
local sound2 = handle:WaitForChild("Sound2") -- change handle to sp if localscript not parented to tool
local soundEvent = sp:WaitForChild("SoundEvent") -- assuming 'sp' is the tool

local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://" .. swinganimationid
local swingtrack = lp.Character.Humanoid:LoadAnimation(anim)

sp.Activated:connect(function()
	if debounce == true then
		debounce = false
		swingtrack:Play()
		soundEvent:FireServer(sound, "play")
		soundEvent:FireServer(sound2, "play")
		swingtrack.Stopped:wait() -- waits for animation to finish more precisely
		soundEvent:FireServer(sound, "stop")
                soundEvent:FireServer(sound, "stop")
		debounce = true
	end
end)
2 Likes

Thank you, the script comments help a lot and are gonna go a long way for me.

1 Like