Unity
com.aurix.voice package for Unity 2021.3+ — C# client, AudioSource-based playback, desktop, mobile and WebGL.
Install#
Window → Package Manager → + → Add package from git URL:
https://github.com/aurix-voice/aurix.git?path=/sdk/unity#v1.13.0The package (com.aurix.voice) contains the managed client, the native aurix-client library for Windows, macOS, Linux and Android, a WebGL bridge, and samples (VoiceQuickstart, WebGLQuickstart, MirrorProximity, NetcodeProximity, Concentus fallback codec) under Package Manager → Samples.
Connect and join#
using Aurix;
var voice = GetComponent<AurixVoiceBehaviour>(); // on a persistent object
voice.WebSocketUrl = token.Endpoint.WsUrl;
voice.Token = token.Token;
voice.ChannelId = token.Channels[0].ChannelId; // joined right after connect
await voice.Connect(); // microphone, playback and PTT are handled by the behaviourAurixVoiceBehaviour owns capture (Unity's Microphone API), playback and push-to-talk and exposes the underlying AurixVoiceClient as voice.Client for everything else — JoinChannelAsync(Guid), LeaveChannelAsync, TransmitToChannelAsync, SetParticipantVolumeAsync, chat, moderation. Use AurixVoiceClient directly only when you bring your own audio pipeline.
Playback and spatial audio#
Every remote participant gets an AurixParticipantAudioSource — an ordinary AudioSource you can parent to the player's avatar. Unity's spatial blend, roll-off and mixer groups apply. AurixListenerTap reports who is speaking for UI rings; AurixGameAudioDucker lowers your music/SFX mixer group while someone talks; AurixLipSync exposes visemes for avatar mouths.
For positional channels send the local player's pose:
await voice.Client.UpdatePositionAsync(channelId, myUserId, new Position3D { X = p.x, Y = p.y, Z = p.z },
new Orientation3D { ForwardX = f.x, ForwardY = f.y, ForwardZ = f.z, UpX = u.x, UpY = u.y, UpZ = u.z }); // 10–20 HzPush-to-talk, VAD, mute#
voice.PushToTalkKey = KeyCode.V; // or PushToTalkAction (Input System); PushToTalkToggle for toggle mode
voice.Vad.Threshold = 0.02f; voice.Vad.HangoverFrames = 8;
voice.SetInputGain(1f);
voice.SetMuted(false);Mobile#
- Android:
RECORD_AUDIOis requested at first capture (PermissionState,RetryMicrophonePermission()); capture goes through Unity'sMicrophoneAPI. - iOS: add
NSMicrophoneUsageDescriptionto the player settings. - Both platforms suspend capture when the app goes to the background and resume on return.
Reconnects#
The client keeps reconnecting with its token while valid (60 minutes). Set voice.TokenRefresher = async ct => await FetchTokenFromYourBackend(); and it fetches a fresh one when a reconnect needs it.
Channel patterns#
| Pattern | Channels per player | Notes |
|---|---|---|
| Co-op / squad | one team | mute = PTT off; nothing positional |
| Shooter with proximity | positional (shard) + team (squad) | transmit on the team channel by default, hold a key to speak locally |
| Open world | positional (shard), optional whisper for direct calls | roster_radius keeps the participant list small |
| Event / stage | audience-shaped channel, hosts with priority | thousands of listeners, a few speakers |
The transmit channel is a client-side choice: join several, send to one, hear all with receive. Positional audio needs positions roughly 10 times a second; between updates the node interpolates.
Latency and quality#
Expect 30–60 ms mouth-to-ear on the same continent over QUIC, more over TURN. Opus runs at 32 kbps with DTX by default; the spending ladder may lower it to 16 kbps when your forecast exceeds the limit. Server-side noise suppression is on by default and costs nothing on the client.
Testing without a full build#
- Two players: the rooms demo in a browser plus your build — they share a cell, so a token from your backend joins the same channel by name.
- Mic path: an
echochannel plays your own voice back through the real pipeline. - Network: throttle UDP on one machine and watch the transport fall back to WebRTC / WebSocket in the SDK's connection state.
Troubleshooting#
| Symptom | Check |
|---|---|
| connected, no audio | capture started? channel grant speak/receive? OS microphone permission? |
| audio but no spatialisation | positions sent on the positional channel id, not the team channel |
| random drops on mobile | the SDK pauses capture in the background by design; resume on foreground |
QUOTA_EXCEEDED on connect | plan concurrency cap or spending ladder step 4 — see Spending limit |