You may have noticed when using the Roblox endorsed weapons that when you aim down sights and shoot the gun, the sound plays louder in your left ear than your right ear.
This is a very common problem with tools. It happens when a sound plays in a tool but your camera is to the left or right of it, so you hear it to the left or right. Example: when using first person, the tool is to the right of the camera.
Here is a video demo using the Roblox endorsed Auto Rifle:
Use headphones so you can hear the difference as I zoom in and out.
So how do we fix this?
The answer is by setting SoundService:SetListener(). The sound listener is the point in 3D space where you “hear” sounds from. It is basically where your ears are.
By default, it is set to workspace.CurrentCamera
. Which means you hear things based on where your camera is. That is why when you zoom in with the auto rifle you hear the sound louder in your left ear.
Here is a visual demo of where the default sound listener is when using the Auto Rifle.
The red square in the left image is where the camera and sound listener are when I am not aiming down sights and the right image is when I am.
As you can see in the right image, the sound listener is very close and to the right of the gun. This means you will hear the gun to your left. In contrast when zoomed out the listener is still right of the gun but since it is farther away the sound is more even.
Solution #1 (the bad one)
One way we can solve the problem is by setting the sound listener to the handle of the tool. That way no matter how far in or out you are zoomed you will hear the fire sounds the same.
This works fine until you realize that now you are hearing all your character sounds loudly in the left ear😅. This is because the character sounds (running, swimming, dying) play from the HumanoidRootPart which is to the left of the tool!
Here is a Demo video from the game Weaponry by @Headstackk (great game).
As you can see when I equip the gun, the sound listener switches to the gun and the footsteps sound plays loudly in the left ear.
Solution #2 (the good one)
Now I will get to the good solution which should be used.
Since we want sounds from the HumanoidRootPart and from the gun to play properly. Instead of setting the sound listener to the gun, we set the sound listener to 10 studs behind the gun. From there both the HumanoidRootPart and gun are in relatively the same place to the sound listener and directly in front of the sound listener so it will play evenly in both ears.
I will be modifying the code of the Roblox endorsed weapons for this example.
The changes will be in WeaponsSystem>Libraries>ShoulderCamera
, starting at line 544. We will only be adding a few lines.
Code and explanation
There are multiple methods of setting the camera listener. You can see the different types in the Enum.ListenerTypes list.
I will be using Enum.ListenerType.CFrame
.
-- this line is line 544
local connection = nil -- create a variable for the RenderStepped connection
-- this code runs when the tool is equipped
self.eventConnections.characterChildAdded = character.ChildAdded:Connect(function(child)
if child:IsA("Tool") then
self.currentTool = child
self:updateZoomState()
-- our code goes here
connection = RunService.RenderStepped:Connect(function()
-- We get the LookVector of the Camera and multiply by -10 to get 10 studs behind
local offset = workspace.CurrentCamera.CFrame.LookVector * -10
-- Then we add that offset to the Handle's CFrame of the Tool
local listeningPoint = child.Handle.CFrame + offset
-- Lastly we call SoundService:SetListener()!
game:GetService("SoundService"):SetListener(Enum.ListenerType.CFrame,listeningPoint)
end)
end
end)
-- this code runs when the tool is unequipped
self.eventConnections.characterChildRemoved = character.ChildRemoved:Connect(function(child)
if child:IsA("Tool") and self.currentTool == child then
self.currentTool = character:FindFirstChildOfClass("Tool")
self:updateZoomState()
-- disconnect the event
connection:Disconnect()
-- reset the Sound listener to the camera
game:GetService("SoundService"):SetListener(Enum.ListenerType.Camera)
end
end)
and that’s it!
The result will be that the sound listener is positioned 10 studs behind the tool no matter how far in or out the camera is zoomed.
Here is a visualization:
(both images show the sound listener in the same location)
Final Result:
(I boosted the sound of the footsteps so that it is audible)
Now you know how to fix the audio for tools properly! Thanks for reading!
P.s. @Headstackk please fix the sounds in Weaponry . I exclusively use Third Person camera lock and the footsteps sound in my left ear is driving me crazy. Thanks.