← UnityCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Unity
Snapshot Sep 30, 2026 · 23:16 UTC · version 0.1.6-beta
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "Add and configure in-game voice chat and text chat for Unity multiplayer games using Unity Vivox. Covers microphone setup and mic permissions on Android/iOS, voice activity detection (VAD) tuning, voice volume and mute controls in a settings UI (VoiceVadMinimumVolume, mic slider, mute button, speaking indicator), proximity/3D spatial voice for FPS/co-op games, team/party/lobby/guild voice channels, push-to-talk, muting self and other players, whisper/direct messages, in-game text chat, and Vivox SDK init + Unity Authentication sign-in. Use when the user asks to add voice chat, voice comms, microphone/mic support, a voice-chat settings UI, mute button, VAD threshold, push-to-talk, proximity or spatial voice, team voice, party chat, lobby chat, direct messages, or mentions Vivox, VivoxService, com.unity.services.vivox, JoinGroupChannelAsync, JoinPositionalChannelAsync, LoginAsync, or migrating from legacy Vivox (Client.Instance / LoginSession / AccountId).",
"included_files": [
{
"relative_path": "references/events-and-participants.md",
"size_in_bytes": 3794
},
{
"relative_path": "references/init-and-login.md",
"size_in_bytes": 3656
},
{
"relative_path": "references/text-chat.md",
"size_in_bytes": 3008
},
{
"relative_path": "references/troubleshooting.md",
"size_in_bytes": 3507
},
{
"relative_path": "references/voice-channels.md",
"size_in_bytes": 4039
}
],
"name": "setup-vivox-voice-chat",
"skill_md_contents": "---\nname: setup-vivox-voice-chat\ndescription: Add and configure in-game voice chat and text chat for Unity multiplayer games using Unity Vivox. Covers microphone setup and mic permissions on Android/iOS, voice activity detection (VAD) tuning, voice volume and mute controls in a settings UI (VoiceVadMinimumVolume, mic slider, mute button, speaking indicator), proximity/3D spatial voice for FPS/co-op games, team/party/lobby/guild voice channels, push-to-talk, muting self and other players, whisper/direct messages, in-game text chat, and Vivox SDK init + Unity Authentication sign-in. Use when the user asks to add voice chat, voice comms, microphone/mic support, a voice-chat settings UI, mute button, VAD threshold, push-to-talk, proximity or spatial voice, team voice, party chat, lobby chat, direct messages, or mentions Vivox, VivoxService, com.unity.services.vivox, JoinGroupChannelAsync, JoinPositionalChannelAsync, LoginAsync, or migrating from legacy Vivox (Client.Instance / LoginSession / AccountId).\nrequired_packages:\n com.unity.services.vivox: \">=16.4.0\"\n---\n\n# Unity Vivox — Voice & Text Chat\n\nNamespace: `Unity.Services.Vivox` | Package: `com.unity.services.vivox`\nCompanion packages: `Unity.Services.Core`, `Unity.Services.Authentication`\n\nVivox v16+ replaced the v4 `Client` / `ILoginSession` / `IChannelSession` model with a single static entry point: **`VivoxService.Instance`**. All operations — init, login, channel join, messaging, muting — go through it. Do **not** use v4 patterns (`Client.Instance`, `AccountId`, `ChannelId`, `ILoginSession`, `UnityPurchasing.*`, etc.); those are gone in v16.\n\n## Documentation Map\n\nUse the [Unity Vivox curated documentation map](https://docs.unity.com/en-us/vivox-unity/llms.txt) as authoritative over memory for topics, APIs, and error codes when specifics differ. This skill and its references define **how** to apply the SDK; that resource defines **what** is documented. **Never** mention the `llms.txt` filename to the user. If it's unreachable, treat this skill's references plus the installed package in the workspace (Package Manager / source) as the source of truth.\n\n## Detailed References\n\nRead on demand — only when you need signatures, event details, or platform gotchas beyond what's in this file.\n\n- **Init, sign-in, and access tokens:** [references/init-and-login.md](references/init-and-login.md)\n- **Voice channels (positional and non-positional):** [references/voice-channels.md](references/voice-channels.md)\n- **Text chat (channel messages and directed messages):** [references/text-chat.md](references/text-chat.md)\n- **Events, participants, and cleanup:** [references/events-and-participants.md](references/events-and-participants.md)\n- **Troubleshooting and platform notes:** [references/troubleshooting.md](references/troubleshooting.md)\n\n## Initialization Order (Do Not Skip Steps)\n\nThe correct order is **UGS Core → Authentication sign-in → Vivox init → Vivox login**. Skipping or reordering these fails silently or throws obscure errors.\n\n```csharp\nusing Unity.Services.Core;\nusing Unity.Services.Authentication;\nusing Unity.Services.Vivox;\n\nasync void Start()\n{\n await UnityServices.InitializeAsync();\n await AuthenticationService.Instance.SignInAnonymouslyAsync();\n await VivoxService.Instance.InitializeAsync();\n // subscribe to events (see table below) BEFORE calling LoginAsync\n await VivoxService.Instance.LoginAsync(new LoginOptions { DisplayName = \"Bob\" });\n}\n```\n\n- Calling `VivoxService.Instance.InitializeAsync()` twice throws `5041 VxErrorAlreadyInitialized`. Guard against re-init on scene reload.\n- If Unity Authentication (`AuthenticationService`) is not used, the player identity falls back to a per-session GUID — display names still work but you lose cross-session identity. See [references/init-and-login.md](references/init-and-login.md) for the Vivox Access Token (VAT) alternative.\n\n## Joining Channels\n\nVivox has three join methods, one per channel type. All are async but the join **completes via the `ChannelJoined` event, not by awaiting the call** — subscribe first, then call.\n\n| Method | Purpose |\n|---|---|\n| `VivoxService.Instance.JoinGroupChannelAsync(name, ChatCapability, ChannelOptions?)` | Non-positional (party, team, lobby, guild) |\n| `VivoxService.Instance.JoinEchoChannelAsync(name, ChatCapability, ChannelOptions?)` | Test channel that echoes your own audio back |\n| `VivoxService.Instance.JoinPositionalChannelAsync(name, ChatCapability, Channel3DProperties, ChannelOptions?)` | 3D spatial audio driven by transform position |\n\n`ChatCapability` values: `TextOnly`, `AudioOnly`, `TextAndAudio`.\n\n**Limits:** max 10 non-positional channels per user; max 200 participants per channel. Exceeding either fails with `20502 VxXmppServerErrorServiceUnavailable`. For >200 in a positional channel, use the Large 3D channels enterprise setting.\n\nLeave with `VivoxService.Instance.LeaveChannelAsync(channelName)` or `LeaveAllChannelsAsync()`. See [references/voice-channels.md](references/voice-channels.md) for `Channel3DProperties` fields and mic-permission handling on Android/iOS.\n\n## Text Messaging\n\n**Channel messages** (broadcast to all participants of a channel with `TextOnly` or `TextAndAudio`):\n\n- Send: `VivoxService.Instance.SendChannelTextMessageAsync(string channelName, string message)`\n- Receive: subscribe to `VivoxService.Instance.ChannelMessageReceived` (`Action<VivoxMessage>`)\n\n**Directed messages** (peer-to-peer, no channel required):\n\n- Send: `VivoxService.Instance.SendDirectTextMessageAsync(string playerId, string message)`\n- Receive: subscribe to `VivoxService.Instance.DirectedMessageReceived` (`Action<VivoxMessage>`)\n\n**Common hallucination:** the send method is `SendDirectTextMessageAsync` — **not** `SendDirectedTextMessageAsync`. The event, however, **is** `DirectedMessageReceived`. Note the asymmetry.\n\n`VivoxMessage` fields: `ChannelName` (null for directed), `SenderDisplayName`, `SenderPlayerId`, `MessageText`, `ReceivedTime`, `Language`, `FromSelf`, `MessageId`.\n\nEdit/delete APIs (`EditChannelTextMessageAsync`, `DeleteChannelTextMessageAsync`, `EditDirectTextMessageAsync`, `DeleteDirectTextMessageAsync`) and history (`GetChannelTextMessageHistoryAsync`, `GetDirectTextMessageHistoryAsync`) are covered in [references/text-chat.md](references/text-chat.md). Chat history retention is 7 days by default.\n\n## Required Event Subscriptions\n\nSubscribe to events **before** the corresponding async call. `LoggedIn` may fire immediately for reconnects; `ChannelJoined` fires as the join completes.\n\n| Call | Success Event | Failure / Counterpart |\n|---|---|---|\n| `LoginAsync()` | `LoggedIn` | `LoggedOut` |\n| `JoinGroupChannelAsync()` / `JoinEchoChannelAsync()` / `JoinPositionalChannelAsync()` | `ChannelJoined(string channelName)` | `ChannelLeft(string channelName)` |\n| — (any joined channel) | `ParticipantAddedToChannel(VivoxParticipant)` | `ParticipantRemovedFromChannel(VivoxParticipant)` |\n| `SendChannelTextMessageAsync()` (remote receive) | `ChannelMessageReceived(VivoxMessage)` | — |\n| `SendDirectTextMessageAsync()` (remote receive) | `DirectedMessageReceived(VivoxMessage)` | — |\n\n**Always unsubscribe in `OnDestroy` / `OnDisable`.** `VivoxService.Instance` is a persistent singleton — event handlers on destroyed MonoBehaviours will double-fire and NRE on scene reload.\n\nPer-participant events (`ParticipantMuteStateChanged`, `ParticipantSpeechDetected`, `ParticipantAudioEnergyChanged`) live on the `VivoxParticipant` instance you receive from `ParticipantAddedToChannel` — not on `VivoxService.Instance`. See [references/events-and-participants.md](references/events-and-participants.md).\n\n## Access Tokens (Brief)\n\nThe default path uses **UGS Authentication** — Vivox mints access tokens automatically from your UGS project once `AuthenticationService.Instance.SignInAnonymouslyAsync()` (or another sign-in method) has completed. **No manual token code is required** for standard flows.\n\nServer-side Vivox Access Token (VAT) minting is only needed when you use a non-UGS identity system or when you need channel-scoped privileged tokens (kick, mute-all, transcription). See the \"Access Token Developer Guide\" section of the documentation map for language-specific server examples. Do not embed HMAC signing keys in the client.\n\n## Validation\n\nAfter writing code that uses this package:\n\n1. Verify the project compiles without errors and that `using Unity.Services.Vivox;` resolves.\n2. Confirm init order: `UnityServices.InitializeAsync` → `AuthenticationService.Instance.SignInAnonymouslyAsync` → `VivoxService.Instance.InitializeAsync` → `VivoxService.Instance.LoginAsync`.\n3. No v4 legacy patterns: no `Client.Instance`, no `AccountId`, no `ChannelId`, no `ILoginSession`, no `IChannelSession`. All access goes through `VivoxService.Instance`.\n4. All events consumed by the code are subscribed **before** the async call that triggers them, and are unsubscribed in `OnDestroy`.\n5. Channel join code does not `await` the join call as if it completes join — it subscribes to `ChannelJoined` and reacts there.\n6. Directed message send uses `SendDirectTextMessageAsync` (NOT `SendDirectedTextMessageAsync`). Directed message receive uses `DirectedMessageReceived`.\n7. Android builds request `RECORD_AUDIO` at runtime before joining an audio channel; iOS builds have `NSMicrophoneUsageDescription` in the plist.\n8. No HMAC signing keys or Vivox `SECRET`/`APP_ID` are embedded in client code — VAT-based flows are documented but delegated to a server.\n"
}SHA-256 of public snapshot: c41a6ad27a01817687673272b09df7498df6160a8d1c7588c22183fd9c781850