# 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 프로젝트를 위해 Vivox 음성 및 텍스트를 설정하는 과정은 다음과 같습니다.

1. Unity Cloud 대시보드에서 계정과 프로젝트를 생성합니다([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. Unity 에디터에서 **Window > Package Manager > Search Unity Registry**를 선택합니다.

3. Vivox를 검색합니다. Install을 선택합니다.

4. **Edit > Project Settings > Services**를 선택하고 프로젝트에 올바른 프로젝트 ID를 연결합니다.

5. **Service**에서 **Vivox**를 선택하고 프로젝트에서 올바른 인증정보를 가져왔는지 확인합니다.

   > **Note:**
   >
   > 필요한 패키지는 manifest.json 파일을 편집하거나 패키지 관리자를 사용하여 직접 추가할 수 있습니다. 이때 이름으로 `com.unity.services.vivox`를 사용하여 **Window > Package Manager > + > Add package by name**을 선택하십시오. 자세한 내용은 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)는 포지셔널 채널에 대화 거리와 오디오 페이드 모델 등 특정 값을 전달하는 데 사용될 수 있는 구조체입니다.

필요에 따라 사용자가 참여할 수 있는 채널에 대한 액세스 제어가 더 필요한 경우, 채널 참여 플로에 [VAT(Vivox 액세스 토큰)](./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)를 참고하시기 바랍니다.
