# Vivox Unity SDK 快速入门指南

> Follow this workflow to get started with Vivox voice and text chat.

Unity 提供 Vivox 服务，作为游戏开发者通过频道式工作流程在用户之间提供语音和文本通信的一种方式，无需投资实现自托管解决方案。

Unity 用于多人游戏通信的语音和文本聊天服务通过管理的托管解决方案提供语音聊天和直接消息文本服务。

将插件添加到游戏中，配置项目设置以立即为项目添加通信功能。在 2D 和 3D 频道中连接无限数量的用户。允许用户控制音量、执行静音操作和管理频道。让用户加入团队聊天。允许用户参与多个频道。

## 在 Unity 项目中启用 Vivox 服务##enable-the-vivox-service-in-a-unity-project

要在 Unity Dashboard 上为 Unity 项目设置 Vivox 语音和文本，请完成以下步骤。

1. 在 Unity Dashboard [https://cloud.unity3d.com](https://cloud.unity3d.com/) 上创建帐户和项目。

2. 在左侧面板中，选择 **Products**。在 **Communication & Safety** 下，选择 **Vivox Voice and Text Chat**。

3. 遵循入门步骤。在入门过程中，您将获得 Vivox API 凭据以在项目中使用。

## 将您的 Unity 项目连接到 Vivox##connect-your-unity-project-to-vivox

要将 Unity 项目连接到 Vivox，请完成以下步骤。

1. 创建或打开本地 Unity 项目。

2. 在编辑器中，选择 **Window > Package Manager > Search Unity Registry**。

3. 搜索 Vivox。选择 Install。

4. 选择 **Edit > Project Settings > Services**，确保项目有与之关联的正确 Project ID。

5. 在 **Service** 下，选择 **Vivox**，并确保已将正确的凭据拉入项目中。

   > **Note:**
   >
   > 您可以通过编辑 manifest.json 文件或使用 Package Manager（选择 **Window > Package Manager > + > Add package by name**，使用 `com.unity.services.vivox` 作为名称）直接添加所需要的包。要了解更多信息，请参阅 Unity 文档中的[项目清单](https://docs.unity3d.com/Manual/upm-manifestPrj.html)。

## 生命周期操作##lifecycle-actions

### Initialize##initialize

使用 Unity Authentication 服务时，Vivox 包会为您处理凭据和令牌。

```cs
using System;
using UnityEngine;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.Vivox;

async void InitializeAsync()
{
    await UnityServices.InitializeAsync();
    await AuthenticationService.Instance.SignInAnonymouslyAsync();

    await VivoxService.Instance.InitializeAsync();
}
```

### 登录##sign-in

初始化 Vivox SDK 后，可以使用 VivoxService 进行登录。

> **Note:**
>
> `LoginOptions` 可以传递到 [`VivoxService.Instance.LoginAsync(LoginOptions options = null)`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_LoginAsync_Unity_Services_Vivox_LoginOptions_) 中以设置 EnableTTS 和 DisplayName 等值。

```cs
 using Unity.Services.Vivox;

public async void LoginToVivoxAsync()
{
    LoginOptions options = new LoginOptions();
    options.DisplayName = UserDisplayName;
    options.EnableTTS = true;
    await VivoxService.Instance.LoginAsync(options);
}
```

### 加入回声频道##join-an-echo-channel

登录后，使用 [`VivoxService.Instance.JoinEchoChannelAsync(string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null)`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_JoinEchoChannelAsync_System_String_Unity_Services_Vivox_ChatCapability_Unity_Services_Vivox_ChannelOptions_) 加入回声频道并在本地测试 Vivox。

```cs
 using Unity.Services.Vivox;

public async void JoinEchoChannelAsync()
{
    string channelToJoin = "Lobby";
    await VivoxService.Instance.JoinEchoChannelAsync(channelToJoin, ChatCapability.TextAndAudio);
}
```

> **Note:**
>
> 在发送第一个加入请求时会创建频道。

确认可以在回声频道中听到自己的声音后，加入位置频道或群组频道即可听到其他参与者的声音。[`VivoxService.Instance.JoinGroupChannelAsync((string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null))`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_JoinGroupChannelAsync_System_String_Unity_Services_Vivox_ChatCapability_Unity_Services_Vivox_ChannelOptions_) 和 [`VivoxService.Instance.JoinPositionalChannelAsync(string channelName, ChatCapability chatCapability, Channel3DProperties positionalChannelProperties, ChannelOptions channelOptions = null)`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_JoinPositionalChannelAsync_System_String_Unity_Services_Vivox_ChatCapability_Unity_Services_Vivox_Channel3DProperties_Unity_Services_Vivox_ChannelOptions_) 可以分别用于加入群组频道和位置频道。[Channel3DProperties](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.Channel3DProperties.html) 是一种可用于传递位置频道特定值（例如对话距离和音频淡化模型）的结构体。

或者，如果您想要更好地控制用户可以加入哪些频道，可以将 [Vivox 访问令牌 (VAT)](./access-token-guide/access-token-guide-toc.md) 集成到您的频道加入流程中。

> **Note:**
>
> 频道名称必须在各种频道类型中具有唯一性。

### 离开语音和文本频道##leave-a-voice-and-text-channel

要从频道中移除用户，请使用 [`VivoxService.Instance.LeaveChannelAsync(string channelName)`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_LeaveChannelAsync_System_String_) 或 [`VivoxService.Instance.LeaveAllChannels()`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_LeaveAllChannelsAsync)。如果可以独立离开多个频道，这些频道名称必须存储在可检索的地方。

```cs
 using Unity.Services.Vivox;

public async void LeaveEchoChannelAsync()
{
    string channelToLeave = "Lobby";
    await VivoxService.Instance.LeaveChannelAsync(channelToLeave);
}
```

要了解更多信息，请参阅[离开频道](./developer-guide/channels/leave-channel.md)。

### 注销用户##sign-out-a-user

要注销用户，请调用 [`VivoxService.Instance.LogoutAsync()`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_LogoutAsync) 方法。用户注销后，Vivox SDK 不会发送或接收任何网络流量。通常仅当退出应用程序时，或者用户可以在应用程序中登录不同帐户的情况下用户从游戏服务器注销时，才进行调用。

```cs
using Unity.Services.Vivox;

public async void LogoutOfVivoxAsync ()
{
    VivoxService.Instance.LogoutAsync;
}
```

要了解更多信息，请参阅[从游戏注销](./developer-guide/vivox-unity-sdk-basics/sign-in-with-custom-id.md)。

## 频道内操作##in-channel-actions

### 处理参与者事件##handle-participant-events

每当有新玩家添加到用户所属的频道或从该频道中移除玩家时，Vivox SDK 都会发布事件。可以使用以下形式订阅这些事件：

* [`VivoxService.Instance.ParticipantAddedToChannel`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_ParticipantAddedToChannel)
* [`VivoxService.Instance.ParticipantRemovedFromChannel`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_ParticipantRemovedFromChannel)

此事件将使用 `VivoxParticipant` 类型的对象进行触发，其中包括参与者加入频道时的 `DisplayName`、`PlayerId` 和 `AudioEnergy` 等重要信息。事件的存在是为了提醒游戏注意对可更改的值（`SpeechDetected, IsMuted` 和 A`udioEnergy`）的任何更改。这些事件如下所示：

* [`VivoxParticipant.ParticipantMuteStateChanged`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.VivoxParticipant.html#Unity_Services_Vivox_VivoxParticipant_ParticipantMuteStateChanged)
* [`VivoxParticipant.ParticipantSpeechDetected`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.VivoxParticipant.html#Unity_Services_Vivox_VivoxParticipant_ParticipantSpeechDetected)
* [`VivoxParticipant.ParticipantAudioEnergyChanged`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.VivoxParticipant.html#Unity_Services_Vivox_VivoxParticipant_ParticipantAudioEnergyChanged)

```cs
using Unity.Service.Vivox;

List<RosterItem> rosterList = new List<RosterItem>();

private void BindSessionEvents(bool doBind)
{
    if(doBind)
    {
        VivoxService.Instance.ParticipantAddedToChannel += onParticipantAddedToChannel;
        VivoxService.Instance.ParticipantRemovedFromChannel += onParticipantRemovedFromChannel;
    }
    else
    {
        VivoxService.Instance.ParticipantAddedToChannel -= onParticipantAddedToChannel;
        VivoxService.Instance.ParticipantRemovedFromChannel -= onParticipantRemovedFromChannel;
    }
}

private void onParticipantAddedToChannel(VivoxParticipant participant)
{
    ///RosterItem is a class intended to store the participant object, and reflect events relating to it into the game's UI.
    ///It is a sample of one way to use these events, and is detailed just below this snippet.
    RosterItem newRosterItem = new RosterItem();
    newRosterItem.SetupRosterItem(participant);
    rosterList.Add(newRosterItem);
}

private void onParticipantRemovedFromChannel(VivoxParticipant participant)
{
    RosterItem rosterItemToRemove = rosterList.FirstOrDefault(p => p.Participant.PlayerId == participant.PlayerId);
    rosterList.Remove(rosterItemToRemove);
}
```

以下代码片段进一步详细说明了 `RosterItem` 可能采用的结构：

```cs
 using Unity.Service.Vivox;
using UnityEngine;

public class RosterItem : MonoBehaviour
{
    public VivoxParticipant Participant;
    public Text PlayerNameText;

    public Image ChatStateImage;
    public Sprite MutedImage;
    public Sprite SpeakingImage;
    public Sprite NotSpeakingImage;

    public SetupRosterItem(VivoxParticipant participant)
    {
        Participant = participant;
        PlayerNameText.text = Participant.DisplayName;
        UpdateChatStateImage();
        Participant.ParticipantMuteStateChanged += UpdateChatStateImage;
        Participant.ParticipantSpeechDetected += UpdateChatStateImage;
    }

    private void UpdateChatStateImage()
    {
        /// Update the UI of the game to the state of the participant
        if (Participant.IsMuted)
        {
            ChatStateImage.sprite = MutedImage;
            ChatStateImage.gameObject.transform.localScale = Vector3.one;
        }
        else
        {
            if (Participant.SpeechDetected)
            {
                ChatStateImage.sprite = SpeakingImage;
                ChatStateImage.gameObject.transform.localScale = Vector3.one;
            }
            else
            {
                ChatStateImage.sprite = NotSpeakingImage;
            }
        }
    }
}
```

要了解更多信息，请参阅[参与者事件](./developer-guide/channels/participant-events.md)。

### 向频道发送文本消息##send-text-messages-to-a-channel

如果游戏加入了启用了文本的频道，则用户可以发送和接收群组文本消息。为了发送消息，游戏会使用 [`VivoxService.Instance.SendChannelTextMessageAsync(string channelName, string message)`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.IVivoxService.html#Unity_Services_Vivox_IVivoxService_SendChannelTextMessageAsync_System_String_System_String_Unity_Services_Vivox_MessageOptions_) 方法。在进行了此 SDK 调用后，该频道中的其他用户会收到 `ChannelMessageReceived` 事件。此事件返回一个 `VivoxMessage` 值，其中包含消息的发送方、文本和发送消息的频道。

```cs
using Unity.Service.Vivox;

private async void SendMessageAsync(string channelName, string message)
{
    VivoxService.Instance.SendChannelTextMessageAsync(channelName, message);
}

private void BindSessionEvents(bool doBind)
{
    VivoxService.Instance.ChannelMessageReceived += onChannelMessageReceived;
}

private void onChannelMessageReceived(VivoxMessage message)
{
    string messageText = message.MessageText;
    string senderID = message.SenderPlayerId;
    string senderDisplayName = message.SenderDisplayName;
    string messageChannel = message.ChannelName;
}
```

要了解更多信息，请参阅[发送和接收群组文本消息](./developer-guide/messaging/channel-messages.md)。

### 使其他参与者静音##mute-other-participants

可以使用本地静音使其他用户对特定用户静音。[`VivoxParticipant.MutePlayerLocally()`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.VivoxParticipant.html#Unity_Services_Vivox_VivoxParticipant_MutePlayerLocally) 函数可阻止用户听到已静音用户，但是频道中的其他用户将继续听到已静音用户。[`VivoxParticipant.UnmutePlayerLocally()`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.VivoxParticipant.html#Unity_Services_Vivox_VivoxParticipant_UnmutePlayerLocally) 可用于将用户取消静音。通常，这些命令应附加到与频道中的特定参与者相关联的 UI 元素。

例如，频道中有 Cynthia、Fernando 和 Wang 三人。Fernando 不希望听到 Wang 的音频。使用本地静音可以允许 Fernando 停止听到 Wang 的音频。但是，Cynthia 可继续听到 Wang，而 Wang 可继续听到 Cynthia 和 Fernando。

```cs
{
if (participant.InAudio && setMute)
{
    participant.MutePlayerLocally
}
else if (participant.InAudio)
{
    participant.UnmutePlayerLocally
}
else
{
    //Tell player to try again
    Debug.Log("Try Again");
}
}
```

要了解更多信息，请参阅[使其他用户对特定用户静音](./developer-guide/muting/mute-other-users.md)。

### 使自己静音##mute-yourself

可通过两种方法使用户的麦克风静音：`AudioInputDevices` 或 `SetTransmissionMode()`。每个方法对不同的场景都有好处。

使用 [`Transmission.None`](https://docs.unity3d.com/Packages/com.unity.services.vivox@latest/index.html?subfolder=/api/Unity.Services.Vivox.TransmissionMode.html) 可阻止玩家的声音在任何频道中被听到。例如：

```cs
await VivoxService.Instance.SetChannelTransmissionModeAsync(Transmission.None, channelName)
```

要了解更多信息，请参阅[使用户的麦克风静音](./developer-guide/muting/mute-user-microphone.md)。

## 后续步骤##next-steps

基本聊天功能正常后，即可使用其他工具扩展 Vivox 功能：

* 添加功能以丰富[文本聊天](./text-chat-guide/text-chat-guide-overview.md)。
* 考虑[语音转文本](./developer-guide/speech-to-text/_index.md)等辅助功能。
* 查看[开发者指南](./developer-guide/_index.md)以了解更多主题和功能。
