Voice API¶
By default everyone is in proximity voice — you hear the people near you, in 3D. The Voice.* API lets a script route voice on purpose: put players on teams that only hear each other, set up a PA announcer everyone hears, make a private party channel, and drop people back to proximity when you're done.
It's server‑authoritative — these calls run on the server (the same channel manager the voice relay routes through), so membership and routing always stay in sync. There's no client‑side voice scripting: capture, encoding, and transport are the engine's job, not yours — you only direct who hears whom.
Player ids are the same strings Player.GetPlayerId() returns, so you can pass a player straight from the Player API into these calls.
The model: channels, talkers, listeners¶
A channel has talkers (whose voice goes into it) and listeners (who hear it). Each player also has one transmit channel — where their own voice goes (proximity by default).
AddTalker(p, ch)—pcan speak intochand hears it (talker ⇒ also a listener).AddListener(p, ch)—phearsch(no talk rights).SetTransmitChannel(p, ch)— sendp's voice tochinstead of proximity.
proximity is the only spatial channel (3D, distance‑based) and the default everyone starts in. Every channel you create is non‑spatial — listeners hear talkers at a flat level, regardless of distance.
Teams (the common case)¶
Players who should only talk to and hear their own team — one call each:
Voice.SetTeam(redPlayerId, "team-red"); // talks to AND hears only team-red
Voice.SetTeam(bluePlayerId, "team-blue");
SetTeam(p, ch) is shorthand for AddTalker(p, ch) + SetTransmitChannel(p, ch).
A PA / announcer everyone hears¶
Voice.CreateChannel("pa", "broadcast");
foreach (/* each player id */) Voice.AddListener(playerId, "pa");
Voice.AddTalker(hostId, "pa");
Voice.SetTransmitChannel(hostId, "pa"); // host now broadcasts to everyone on "pa"
Creating channels¶
Voice.CreateChannel("team-red"); // type defaults to "team"
Voice.CreateChannel("pa", "broadcast");
Voice.DestroyChannel("team-red");
CreateChannel(id, type) — type is one of team, party, broadcast (alias pa), global, or proximity (anything unrecognized falls back to team). You can usually skip it: adding the first talker/listener auto‑creates the channel, and channels are auto‑removed once empty. Use CreateChannel when you want a specific type up front.
Fine‑grained membership¶
Voice.AddTalker(p, "ch"); // p talks into ch (and hears it)
Voice.AddListener(p, "ch"); // p hears ch
Voice.RemoveMember(p, "ch"); // remove p from ch (talker + listener)
Voice.SetTransmitChannel(p, "ch"); // p's voice goes to ch
Voice.ClearTransmitChannel(p); // p's voice goes back to proximity
Back to normal¶
Voice.ResetVoice(p); // remove p from every channel + clear transmit -> plain proximity
ResetVoice is your safe recovery hatch — call it when a match ends, or in OnPlayerLeft, so nobody is left stuck in a stale channel.
Server‑side, string ids
Every Voice.* call takes the string player id from Player.GetPlayerId() and runs on the server, so it takes effect consistently for everyone. The API intentionally exposes only channel routing — not the underlying voice capture/transport.
Quick reference¶
| Call | Effect |
|---|---|
Voice.CreateChannel(id, type="team") |
create a channel (team · party · broadcast/pa · global · proximity) |
Voice.DestroyChannel(id) |
destroy a channel |
Voice.AddTalker(playerId, channelId) |
player speaks into the channel and hears it |
Voice.AddListener(playerId, channelId) |
player hears the channel |
Voice.RemoveMember(playerId, channelId) |
remove player from the channel |
Voice.SetTransmitChannel(playerId, channelId) |
send player's voice to the channel |
Voice.ClearTransmitChannel(playerId) |
send player's voice back to proximity |
Voice.SetTeam(playerId, channelId) |
shorthand: talk to and hear only that channel |
Voice.ResetVoice(playerId) |
back to plain proximity; clears all channel membership |
→ Player ids come from the Player API. For an NPC's spoken (TTS) voice, see AI NPCs › Voice.