Unreal Engine
AurixVoice plugin for UE 5.3 – 5.8 — native UDP/QUIC transport, subsystem API, positional audio and capture on Windows, Linux, macOS and Android.
Install#
- Download
AurixVoice-unreal-1.13.0.zipfrom the release and unzip it into<Project>/Plugins/AurixVoice/. - Add
"AurixVoice"toPublicDependencyModuleNamesin your game module'sBuild.cs. - Enable the plugin in Edit → Plugins → Audio and restart the editor.
The plugin bundles the native aurix-client library for Win64, Linux x86_64/arm64, macOS and Android (SupportedTargetPlatforms in the .uplugin). Console platforms are not part of the public release.
Connect and join#
#include "AurixVoiceSubsystem.h"
UAurixVoiceSubsystem* Voice = GetGameInstance()->GetSubsystem<UAurixVoiceSubsystem>();
FAurixVoiceSettings Settings;
Settings.WebSocketUrl = TokenResponse.Endpoint.WsUrl; // from your backend's /v1/tokens call
Settings.Token = TokenResponse.Token;
Voice->OnSessionReady.AddDynamic(this, &AMyPC::OnVoiceReady);
Voice->Connect(Settings);
// in OnVoiceReady:
FGuid Channel; UAurixVoiceSubsystem::ParseUuid(TokenResponse.Channels[0].ChannelId, Channel);
int64 RequestId;
Voice->JoinChannel(Channel, TEXT(""), RequestId);
Voice->StartCapture(); // default device (-1); GetCaptureDevices() to pick oneConnect is asynchronous; bind OnSessionReady / OnDisconnected / OnChannelJoined / OnParticipantSpeaking / OnRequestFailed on the subsystem (also exposed to Blueprints) to drive UI.
Positional audio#
Feed the listener (local player) every tick or at 10–20 Hz; the plugin interpolates.
Voice->UpdateOwnPosition(ProximityChannel, Pawn->GetActorLocation(), Pawn->GetActorRotation()); // WorldToMeters = 100 by defaultRemote participants are spatialised by the engine: each one is a UAurixParticipantSoundWave playing through a component you can attach to the character, so attenuation, occlusion and reverb settings are your normal Unreal audio setup (UpdatePositions feeds other players' transforms when the server mixes for you). The channel's positional_config on the server (range, roll-off, directionality) decides who is audible at all.
Push-to-talk, VAD, mute#
Voice->SetPushToTalkPressed(bPttHeld); // or bind an Enhanced Input action
Voice->SetMuted(false); // plain mute toggle
Voice->SetVoiceActivityDetector(0.02f, 8); // threshold, hang-over frames
Voice->SetVadGate(true);
Voice->SetInputGain(1.0f);
Voice->SetBitrate(24000); // Opus, bits per secondSeveral channels#
Join a positional channel for proximity and a team channel for the squad, then route the microphone with SetTransmission / SetChannelFocus (or let the default "all joined channels" stand). Priority speakers (priority: true in the token grant) duck the rest automatically.
Reconnects and tokens#
The subsystem reconnects on its own with the last token while it is valid (60 minutes). Set a fresh one with SetToken() from your backend before a reconnect after that — tokens are only needed to (re)connect, not to stay connected; OnRecovering / OnFailedToRecover tell you when it matters.
Packaging notes#
- Windows: nothing extra. Linux servers: the plugin is client-only; a dedicated server does not load it.
- Firewalls: the client speaks AURX over UDP (QUIC optional) to the node's media port; outbound UDP must be allowed. It falls back to the TLS tunnel automatically.
- Logging:
LogAurixVoicecategory; set it toVerbosefor connection diagnostics.
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 |