setup-vivox-voice-chat

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Unity Vivox — Voice & Text Chat

Unity Vivox — 语音与文本聊天

Namespace:
Unity.Services.Vivox
| Package:
com.unity.services.vivox
Companion packages:
Unity.Services.Core
,
Unity.Services.Authentication
Vivox 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.
Namespace:
Unity.Services.Vivox
| Package:
com.unity.services.vivox
Companion packages:
Unity.Services.Core
,
Unity.Services.Authentication
Vivox v16+ 替换了v4版本的
Client
/
ILoginSession
/
IChannelSession
模型,采用单一静态入口点:
VivoxService.Instance
。所有操作——初始化、登录、加入频道、消息发送、静音——都通过该入口点执行。请勿使用v4模式(
Client.Instance
AccountId
ChannelId
ILoginSession
UnityPurchasing.*
等);这些在v16版本中已被移除。

Documentation Map

文档地图

Use the Unity Vivox curated documentation map 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.
当具体内容存在差异时,请以Unity Vivox 精选文档地图作为权威参考,涵盖主题、API和错误代码。本技能及其参考资料定义了SDK的应用方式;该资源定义了已记录的内容。绝对不要向用户提及
llms.txt
文件名。如果无法访问该资源,则以本技能的参考资料加上工作区中已安装的包(Package Manager/源代码)作为事实依据。

Detailed References

详细参考资料

Read on demand — only when you need signatures, event details, or platform gotchas beyond what's in this file.
  • Init, sign-in, and access tokens: references/init-and-login.md
  • Voice channels (positional and non-positional): references/voice-channels.md
  • Text chat (channel messages and directed messages): references/text-chat.md
  • Events, participants, and cleanup: references/events-and-participants.md
  • Troubleshooting and platform notes: references/troubleshooting.md
按需阅读——仅当需要超出本文档范围的签名、事件详情或平台注意事项时才查看。
  • 初始化、登录和访问令牌: references/init-and-login.md
  • 语音频道(位置型与非位置型): references/voice-channels.md
  • 文本聊天(频道消息与定向消息): references/text-chat.md
  • 事件、参与者与清理: references/events-and-participants.md
  • 故障排除与平台说明: references/troubleshooting.md

Initialization Order (Do Not Skip Steps)

初始化顺序(请勿跳过步骤)

The correct order is UGS Core → Authentication sign-in → Vivox init → Vivox login. Skipping or reordering these fails silently or throws obscure errors.
csharp
using Unity.Services.Core;
using Unity.Services.Authentication;
using Unity.Services.Vivox;

async void Start()
{
    await UnityServices.InitializeAsync();
    await AuthenticationService.Instance.SignInAnonymouslyAsync();
    await VivoxService.Instance.InitializeAsync();
    // subscribe to events (see table below) BEFORE calling LoginAsync
    await VivoxService.Instance.LoginAsync(new LoginOptions { DisplayName = "Bob" });
}
  • Calling
    VivoxService.Instance.InitializeAsync()
    twice throws
    5041 VxErrorAlreadyInitialized
    . Guard against re-init on scene reload.
  • 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 for the Vivox Access Token (VAT) alternative.
正确顺序为 UGS Core → Authentication登录 → Vivox初始化 → Vivox登录。跳过或打乱顺序会导致静默失败或抛出模糊错误。
csharp
using Unity.Services.Core;
using Unity.Services.Authentication;
using Unity.Services.Vivox;

async void Start()
{
    await UnityServices.InitializeAsync();
    await AuthenticationService.Instance.SignInAnonymouslyAsync();
    await VivoxService.Instance.InitializeAsync();
    // 在调用LoginAsync之前订阅事件(见下表)
    await VivoxService.Instance.LoginAsync(new LoginOptions { DisplayName = "Bob" });
}
  • 两次调用
    VivoxService.Instance.InitializeAsync()
    会抛出
    5041 VxErrorAlreadyInitialized
    错误。需防止场景重载时重复初始化。
  • 如果未使用Unity Authentication(
    AuthenticationService
    ),玩家身份将回退到会话级GUID——显示名称仍然可用,但会失去跨会话身份。有关Vivox访问令牌(VAT)的替代方案,请查看references/init-and-login.md

Joining Channels

加入频道

Vivox 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.
MethodPurpose
VivoxService.Instance.JoinGroupChannelAsync(name, ChatCapability, ChannelOptions?)
Non-positional (party, team, lobby, guild)
VivoxService.Instance.JoinEchoChannelAsync(name, ChatCapability, ChannelOptions?)
Test channel that echoes your own audio back
VivoxService.Instance.JoinPositionalChannelAsync(name, ChatCapability, Channel3DProperties, ChannelOptions?)
3D spatial audio driven by transform position
ChatCapability
values:
TextOnly
,
AudioOnly
,
TextAndAudio
.
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.
Leave with
VivoxService.Instance.LeaveChannelAsync(channelName)
or
LeaveAllChannelsAsync()
. See references/voice-channels.md for
Channel3DProperties
fields and mic-permission handling on Android/iOS.
Vivox提供三种加入方法,对应三种频道类型。所有方法均为异步,但加入操作通过
ChannelJoined
事件完成,而非等待调用完成
——请先订阅事件,再调用方法。
方法用途
VivoxService.Instance.JoinGroupChannelAsync(name, ChatCapability, ChannelOptions?)
非位置型(队伍、团队、大厅、公会)
VivoxService.Instance.JoinEchoChannelAsync(name, ChatCapability, ChannelOptions?)
测试频道,会将你的音频回声传回
VivoxService.Instance.JoinPositionalChannelAsync(name, ChatCapability, Channel3DProperties, ChannelOptions?)
由Transform位置驱动的3D空间音频
ChatCapability
取值:
TextOnly
AudioOnly
TextAndAudio
限制: 每个用户最多可加入10个非位置型频道;每个频道最多容纳200名参与者。超出任一限制会失败并返回
20502 VxXmppServerErrorServiceUnavailable
。如果位置型频道需要容纳超过200人,请使用企业级的大型3D频道设置。
使用
VivoxService.Instance.LeaveChannelAsync(channelName)
LeaveAllChannelsAsync()
离开频道。有关
Channel3DProperties
字段及Android/iOS平台的麦克风权限处理,请查看references/voice-channels.md

Text Messaging

文本消息

Channel messages (broadcast to all participants of a channel with
TextOnly
or
TextAndAudio
):
  • Send:
    VivoxService.Instance.SendChannelTextMessageAsync(string channelName, string message)
  • Receive: subscribe to
    VivoxService.Instance.ChannelMessageReceived
    (
    Action<VivoxMessage>
    )
Directed messages (peer-to-peer, no channel required):
  • Send:
    VivoxService.Instance.SendDirectTextMessageAsync(string playerId, string message)
  • Receive: subscribe to
    VivoxService.Instance.DirectedMessageReceived
    (
    Action<VivoxMessage>
    )
Common hallucination: the send method is
SendDirectTextMessageAsync
not
SendDirectedTextMessageAsync
. The event, however, is
DirectedMessageReceived
. Note the asymmetry.
VivoxMessage
fields:
ChannelName
(null for directed),
SenderDisplayName
,
SenderPlayerId
,
MessageText
,
ReceivedTime
,
Language
,
FromSelf
,
MessageId
.
Edit/delete APIs (
EditChannelTextMessageAsync
,
DeleteChannelTextMessageAsync
,
EditDirectTextMessageAsync
,
DeleteDirectTextMessageAsync
) and history (
GetChannelTextMessageHistoryAsync
,
GetDirectTextMessageHistoryAsync
) are covered in references/text-chat.md. Chat history retention is 7 days by default.
频道消息(广播给所有
TextOnly
TextAndAudio
频道的参与者):
  • 发送:
    VivoxService.Instance.SendChannelTextMessageAsync(string channelName, string message)
  • 接收:订阅
    VivoxService.Instance.ChannelMessageReceived
    Action<VivoxMessage>
定向消息(点对点,无需频道):
  • 发送:
    VivoxService.Instance.SendDirectTextMessageAsync(string playerId, string message)
  • 接收:订阅
    VivoxService.Instance.DirectedMessageReceived
    Action<VivoxMessage>
常见误区: 发送方法是
SendDirectTextMessageAsync
——不是
SendDirectedTextMessageAsync
。但事件名称确实是
DirectedMessageReceived
,请注意这种不对称性。
VivoxMessage
字段:
ChannelName
(定向消息为null)、
SenderDisplayName
SenderPlayerId
MessageText
ReceivedTime
Language
FromSelf
MessageId
编辑/删除API(
EditChannelTextMessageAsync
DeleteChannelTextMessageAsync
EditDirectTextMessageAsync
DeleteDirectTextMessageAsync
)和历史记录(
GetChannelTextMessageHistoryAsync
GetDirectTextMessageHistoryAsync
)在references/text-chat.md中有详细说明。聊天历史记录默认保留7天。

Required Event Subscriptions

必备事件订阅

Subscribe to events before the corresponding async call.
LoggedIn
may fire immediately for reconnects;
ChannelJoined
fires as the join completes.
CallSuccess EventFailure / Counterpart
LoginAsync()
LoggedIn
LoggedOut
JoinGroupChannelAsync()
/
JoinEchoChannelAsync()
/
JoinPositionalChannelAsync()
ChannelJoined(string channelName)
ChannelLeft(string channelName)
— (any joined channel)
ParticipantAddedToChannel(VivoxParticipant)
ParticipantRemovedFromChannel(VivoxParticipant)
SendChannelTextMessageAsync()
(remote receive)
ChannelMessageReceived(VivoxMessage)
SendDirectTextMessageAsync()
(remote receive)
DirectedMessageReceived(VivoxMessage)
Always unsubscribe in
OnDestroy
/
OnDisable
.
VivoxService.Instance
is a persistent singleton — event handlers on destroyed MonoBehaviours will double-fire and NRE on scene reload.
Per-participant events (
ParticipantMuteStateChanged
,
ParticipantSpeechDetected
,
ParticipantAudioEnergyChanged
) live on the
VivoxParticipant
instance you receive from
ParticipantAddedToChannel
— not on
VivoxService.Instance
. See references/events-and-participants.md.
请在对应的异步调用之前订阅事件。对于重连场景,
LoggedIn
可能会立即触发;
ChannelJoined
会在加入完成时触发。
调用成功事件失败/对应事件
LoginAsync()
LoggedIn
LoggedOut
JoinGroupChannelAsync()
/
JoinEchoChannelAsync()
/
JoinPositionalChannelAsync()
ChannelJoined(string channelName)
ChannelLeft(string channelName)
—(任一已加入的频道)
ParticipantAddedToChannel(VivoxParticipant)
ParticipantRemovedFromChannel(VivoxParticipant)
SendChannelTextMessageAsync()
(远程接收)
ChannelMessageReceived(VivoxMessage)
SendDirectTextMessageAsync()
(远程接收)
DirectedMessageReceived(VivoxMessage)
务必在
OnDestroy
/
OnDisable
中取消订阅。
VivoxService.Instance
是持久化单例——已销毁MonoBehaviour上的事件处理程序会在场景重载时重复触发并引发空引用异常(NRE)。
针对参与者的事件(
ParticipantMuteStateChanged
ParticipantSpeechDetected
ParticipantAudioEnergyChanged
)存在于从
ParticipantAddedToChannel
获取的
VivoxParticipant
实例上——而非
VivoxService.Instance
。详情请查看references/events-and-participants.md

Access Tokens (Brief)

访问令牌(简述)

The 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.
Server-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.
默认流程使用UGS Authentication——一旦
AuthenticationService.Instance.SignInAnonymouslyAsync()
(或其他登录方法)完成,Vivox会自动从你的UGS项目生成访问令牌。标准流程无需手动编写令牌相关代码
仅当使用非UGS身份系统,或需要频道范围的特权令牌(踢人、全员静音、转录)时,才需要在服务器端生成Vivox访问令牌(VAT)。请查看文档地图中的“Access Token Developer Guide”部分获取各语言的服务器示例。请勿在客户端嵌入HMAC签名密钥。

Validation

验证

After writing code that uses this package:
  1. Verify the project compiles without errors and that
    using Unity.Services.Vivox;
    resolves.
  2. Confirm init order:
    UnityServices.InitializeAsync
    AuthenticationService.Instance.SignInAnonymouslyAsync
    VivoxService.Instance.InitializeAsync
    VivoxService.Instance.LoginAsync
    .
  3. No v4 legacy patterns: no
    Client.Instance
    , no
    AccountId
    , no
    ChannelId
    , no
    ILoginSession
    , no
    IChannelSession
    . All access goes through
    VivoxService.Instance
    .
  4. All events consumed by the code are subscribed before the async call that triggers them, and are unsubscribed in
    OnDestroy
    .
  5. Channel join code does not
    await
    the join call as if it completes join — it subscribes to
    ChannelJoined
    and reacts there.
  6. Directed message send uses
    SendDirectTextMessageAsync
    (NOT
    SendDirectedTextMessageAsync
    ). Directed message receive uses
    DirectedMessageReceived
    .
  7. Android builds request
    RECORD_AUDIO
    at runtime before joining an audio channel; iOS builds have
    NSMicrophoneUsageDescription
    in the plist.
  8. No HMAC signing keys or Vivox
    SECRET
    /
    APP_ID
    are embedded in client code — VAT-based flows are documented but delegated to a server.
编写完使用本包的代码后:
  1. 验证项目编译无错误,且
    using Unity.Services.Vivox;
    可正确解析。
  2. 确认初始化顺序:
    UnityServices.InitializeAsync
    AuthenticationService.Instance.SignInAnonymouslyAsync
    VivoxService.Instance.InitializeAsync
    VivoxService.Instance.LoginAsync
  3. 无v4旧版模式:无
    Client.Instance
    、无
    AccountId
    、无
    ChannelId
    、无
    ILoginSession
    、无
    IChannelSession
    。所有访问均通过
    VivoxService.Instance
    进行。
  4. 代码使用的所有事件均在触发它们的异步调用之前订阅,并在
    OnDestroy
    中取消订阅。
  5. 频道加入代码未将join调用视为完成操作而
    await
    ——而是订阅
    ChannelJoined
    并在此处做出响应。
  6. 定向消息发送使用
    SendDirectTextMessageAsync
    (而非
    SendDirectedTextMessageAsync
    )。定向消息接收使用
    DirectedMessageReceived
  7. Android构建在加入音频频道前运行时请求
    RECORD_AUDIO
    权限;iOS构建的plist中包含
    NSMicrophoneUsageDescription
  8. 客户端代码中未嵌入HMAC签名密钥或Vivox的
    SECRET
    /
    APP_ID
    ——基于VAT的流程已文档化,但需委托给服务器处理。