Thanks for your help.
So currently my system only somewhat works, it works, its just only works on the client.
I am trying to route everyone’s mics as long as their AudioDeviceInput is not muted, and they are on the authorized team to a single ChannelMixer (All players → Channel Mixer). And then also route this single Channel Mixer to all players (Channel Mixer → All Players). Also when I say all players I mean all players that match a single criteria. I also added reverb to this channel mixer just so I can identify weather this works or not. Currently it is working, but only the client can hear it (I know this because when I tested with two players only I could hear my own reverb, same for the other player).
Local Script in StarterPlayerScripts:
local AudioOutput
local AudioInput
function UpdatePlayer()
if game.Players.LocalPlayer.Team == game.Teams["Authorized Team"] then
if AudioOutput == nil then
-- Create Audio Output (for listening to the shared channel)
AudioOutput = Instance.new("AudioDeviceOutput", game.Workspace.Camera)
local wireOut = Instance.new("Wire", AudioOutput)
wireOut.SourceInstance = game.Workspace.SharedRadioChannelMixer.AudioReverb
wireOut.TargetInstance = AudioOutput
-- Create Audio Input (for sending to the shared channel)
AudioInput = Instance.new("AudioDeviceInput", game.Workspace.Camera)
AudioInput.Player = game.Players.LocalPlayer
AudioInput.Muted = true
local wireIn = Instance.new("Wire", AudioInput)
wireIn.SourceInstance = AudioInput
wireIn.TargetInstance = game.Workspace.SharedRadioChannelMixer
-- UI Toggle for muting/unmuting microphone
local toggleButton = game.Players.LocalPlayer.PlayerGui:FindFirstChild("ToggleUI") and game.Players.LocalPlayer.PlayerGui.ToggleUI:FindFirstChild("ToggleButton")
if toggleButton then
toggleButton.MouseButton1Click:Connect(function()
AudioInput.Muted = not AudioInput.Muted
toggleButton.Text = tostring(AudioInput.Muted)
end)
toggleButton.Text = tostring(AudioInput.Muted)
end
end
else
if AudioOutput ~= nil then
AudioOutput:Destroy()
AudioOutput = nil
end
if AudioInput ~= nil then
AudioInput:Destroy()
AudioInput = nil
end
end
end
repeat task.wait() until game.Players.LocalPlayer.Character
UpdatePlayer()
game.Players.LocalPlayer:GetAttributeChangedSignal("Team"):Connect(function()
UpdatePlayer()
end)
game.Players.LocalPlayer.CharacterAdded:Connect(function()
UpdatePlayer()
end)
You cannot fully convert this script to server-side because AudioDeviceInput, AudioDeviceOutput, Wire, and most voice-related APIs in Roblox require client-side context. These instances are Local-only and will not replicate from the server.
Server
local rs = game:GetService("ReplicatedStorage")
local ev = Instance.new("RemoteEvent")
ev.Name = "VoiceToggle"
ev.Parent = rs
game.Players.PlayerAdded:Connect(function(plr)
local function checkTeam()
ev:FireClient(plr, plr.Team == game.Teams["Authorized Team"])
end
plr:GetPropertyChangedSignal("Team"):Connect(checkTeam)
checkTeam()
end)
Client
local rs = game:GetService("ReplicatedStorage")
local ev = rs:WaitForChild("VoiceToggle")
local cam = workspace.CurrentCamera
local plr = game.Players.LocalPlayer
local gui = plr:WaitForChild("PlayerGui")
local out, input
function setupVoice(state)
if state then
if not out then
out = Instance.new("AudioDeviceOutput", cam)
local wOut = Instance.new("Wire", out)
wOut.SourceInstance = workspace.SharedRadioChannelMixer.AudioReverb
wOut.TargetInstance = out
input = Instance.new("AudioDeviceInput", cam)
input.Player = plr
input.Muted = true
local wIn = Instance.new("Wire", input)
wIn.SourceInstance = input
wIn.TargetInstance = workspace.SharedRadioChannelMixer
local b = gui:FindFirstChild("ToggleUI")
b = b and b:FindFirstChild("ToggleButton")
if b then
b.MouseButton1Click:Connect(function()
input.Muted = not input.Muted
b.Text = tostring(input.Muted)
end)
b.Text = tostring(input.Muted)
end
end
else
if out then out:Destroy() out = nil end
if input then input:Destroy() input = nil end
end
end
ev.OnClientEvent:Connect(setupVoice)
Add a RemoteEvent named VoiceSetup to ReplicatedStorage (or rename it)
Think that’s the furthest it can be pushed to server-side.
I found a fix to make it server sided, but now I think I broke roblox’s default voice chat somehow because other players can only hear when the AudioDeviceInput instance I Created is not muted instead of still being able to hear other players in proximity with ROBLOX"s default voice chat.
Im not sure how I even could have possibly broke it but maybe someone has more knowledge on this than I do.
Server:
function UpdatePlayer(plr:Player)
if plr.Team == game.Teams["Authorized Team"] then
local Mic = Instance.new("AudioDeviceInput", plr)
Mic.Player = plr
Mic.Name = "RadioMicrophone"
Mic.Muted = true
local Wire = Instance.new("Wire", Mic)
Wire.TargetInstance = game.Workspace.SharedRadioChannelMixer
Wire.SourceInstance = Mic
else
if plr:FindFirstChild("RadioMicrophone") then
plr.RadioMicrophone:Destroy()
end
end
end
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function()
UpdatePlayer(plr)
end)
plr:GetAttributeChangedSignal("Team"):Connect(function()
UpdatePlayer(plr)
end)
end)
Client:
local AudioOutput
function UpdatePlayer()
if game.Players.LocalPlayer.Team == game.Teams["Authorized Team"] then
if AudioOutput == nil then
-- Create Audio Output (for listening to the shared channel)
AudioOutput = Instance.new("AudioDeviceOutput", game.Workspace.Camera)
local wireOut = Instance.new("Wire", AudioOutput)
wireOut.SourceInstance = game.Workspace.SharedRadioChannelMixer.AudioReverb
wireOut.TargetInstance = AudioOutput
end
else
if AudioOutput ~= nil then
AudioOutput:Destroy()
AudioOutput = nil
end
end
end
repeat task.wait() until game.Players.LocalPlayer.Character
UpdatePlayer()
game.Players.LocalPlayer:GetAttributeChangedSignal("Team"):Connect(function()
UpdatePlayer()
end)
game.Players.LocalPlayer.CharacterAdded:Connect(function()
UpdatePlayer()
end)
Tool (Regular script, not local script):
repeat task.wait() until game.Players[script.Parent.Parent.Parent.Name]
local plr:Player = script.Parent.Parent.Parent
print(plr)
local AudioInput = plr:WaitForChild("RadioMicrophone")
script.Parent.Activated:Connect(function()
AudioInput.Muted = not AudioInput.Muted
if AudioInput.Muted == true then
script.Parent.Handle.Part.BrickColor = BrickColor.new("Really red") else script.Parent.Handle.Part.BrickColor = BrickColor.new("Neon green")
end
end)