Vivox Unity SDK quickstart guide

Unity offers the Vivox service as a way for game developers to provide voice and text communications between users through a channel-style workflow without the need to invest in a self-hosted solution.

Unity's Voice and Text chat service for multiplayer communication offers a voice chat and direct message text service with a managed hosted solution.

Plug in to your game and configure your project settings to immediately add communications to your project. Connect an unlimited number of users in 2D and 3D channels. Allow users to control voice volume, perform mute actions, and manage channels. Place users in team chat. Allow users to participate in multiple channels.

Enable the Vivox service in a Unity project

To set up Vivox Voice and Text for a Unity project on the Unity Dashboard, complete the following steps.

  1. Create an account and project on the Unity Cloud Dashboard: https://cloud.unity3d.com.

  2. On the left pane, select Products. Under Community, select Vivox Voice Chat or Vivox Text Chat.

  3. Follow the onboarding steps. During the onboarding process, you are provided with Vivox API credentials to use in your project.

Connect your Unity project to Vivox

To connect your Unity project to Vivox, complete the following steps.

  1. Create or open your local Unity project.

  2. In the Editor, select Window > Package Manager > Search Unity Registry.

  3. Search for Vivox. Select Install.

  4. Select Edit > Project Settings > Services and ensure that your project has the correct project ID associated with it.

  5. Under Service, select Vivox, and ensure that the correct credentials have been pulled into the project.

    Note: You can directly add required packages by editing the manifest.json file or by using the package manager (select Window > Package Manager > + > Add package by name by using com.unity.services.vivox as the name.). For more information, see the Unity documentation on the Project manifest.

Lifecycle actions

Initialize

When using Unity Authentication Services, the Vivox package handles credentials and tokens for you.

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

After you initialize the Vivox SDK, the VivoxService can be used to log in.

Note: LoginOptions can be passed into VivoxService.Instance.LoginAsync(LoginOptions options = null) to set values like EnableTTS and DisplayName.

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

After logging in, VivoxService.Instance.JoinEchoChannelAsync(string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null) can be used to join an echo channel and test Vivox locally.

using Unity.Services.Vivox;

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

Note:: Channels are created at the moment the first join request is sent.

After confirming that you can hear your voice in an echo channel, join a positional or group channel to hear other participants. VivoxService.Instance.JoinGroupChannelAsync((string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null)) and VivoxService.Instance.JoinPositionalChannelAsync(string channelName, ChatCapability chatCapability, Channel3DProperties positionalChannelProperties, ChannelOptions channelOptions = null) can be used to join group channels and positional channels, respectively. Channel3DProperties is a struct that can be used to pass positional channel specific values like conversational distance and the audio fade model.

Note: Channel names must be unique across the channel types.

Leave a voice and text channel

To remove a user from the channel use VivoxService.Instance.LeaveChannel(string channelName) or VivoxService.Instance.LeaveAllChannels(). If more then one channel can be left independently, those channel names must be stored somewhere retrievable.

using Unity.Services.Vivox;

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

For more information, see Leave a channel.

Sign out a user

To sign out a user, call the VivoxService.Instance.LogoutAsync() method. After the user is signed out, there is no network traffic to or from the Vivox SDK. This is typically only called when quitting the application, or in the scenario where a user can sign in to different accounts within the app, when signing the user out of the game server.

using Unity.Services.Vivox;

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

For more information, see Sign out of a game.

In-channel actions

Handle participant events

The Vivox SDK posts events whenever a new player is added to or removed from a channel the user is a part of. These events can be subscribed to as:

  • VivoxService.Instance.ParticipantAddedToChannel
  • VivoxService.Instance.ParticipantRemovedFromChannel

This event will fire with an object of type VivoxParticipant, which includes important information like the DisplayName, PlayerId, and AudioEnergy of the participant at the moment they joined the channel. Events exist to alert the game to any changes to the values capable of changing (SpeechDetected, IsMuted, and AudioEnergy). These events are as follows:

  • VivoxParticipant.ParticipantMuteStateChanged
  • VivoxParticipant.ParticipantSpeechDetectedStateChanged
  • VivoxParticipant.ParticipantAudioEnergyChanged
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);
}

The following code snippet further details the structure RosterItem may take:

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;
            }
        }
    }
}

For more information, see Participant events.

Send text messages to a channel

If the game has joined a channel with text enabled, users can send and receive group text messages. To send messages, the game uses the VivoxService.Instance.SendChannelTextMessageAsync(string channelName, string message) method. After this SDK call is made, other users in that channel receive a hannelMessageReceived event. This event returns a VivoxMessage value, which contains the message's sender, text, and the channel it was sent in.

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;
}

For more information, see Send and receive group text messages.

Mute other participants

You can mute other users for a specific user by using a local mute. The VivoxParticipant.MuteUserLocally() function prevents a user from hearing a muted user, but other users in the channel will continue to hear the muted user. VivoxParticipant.UnmuteUserLocally() can be used to unmute the user. Generally these commands should be attached to UI elements tied to the specific participants of the channel as they come in.

For example, Cynthia, Fernando, and Wang are in a channel. Fernando does not want to hear Wang’s audio. By using a local mute, you can allow Fernando to stop hearing Wang’s audio. However, Cynthia continues to hear Wang, and Wang continues to hear Cynthia and Fernando.

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

For more information, see Mute other users for a specific user.

Mute yourself

There are two methods for muting a user’s microphone: AudioInputDevices or SetTransmissionMode(). Each method is beneficial for different scenarios.

Use can also use Transmission.None to prevent a player from being heard in any channels. For example:

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

For more information, see Mute a user's microphone.