Use case: Manage voice chat
You can use the Vivox voice chat service to integrate voice channels in your rooms and facilitate collaboration between participants.
Before you start
Before you manage your voice chat, make sure you configured Vivox. Then make sure you manage your room.
How do I...?
Instantiate the Vivox voice chat service
To instantiate the Vivox service, see the following steps:
- Go to your
PlatformServicesscript in yourAssets/Scriptsdirectory. - In your
PlatformServicesscript file, update thePlatformServicesclass with a public reference toIVoiceService,IPresenceVivoxServiceComponents, and a private reference toPresenceVivoxService.
static VivoxService s_VivoxService;
public static IVoiceService VoiceService => s_VivoxService;
public static IPresenceVivoxServiceComponents PresenceVivoxServiceComponents => s_VivoxService;
- Initialize the services in the
InitializeAsyncmethod. The variables provided in the constructor are defined in get started and in the Identity authentication guide.
public static async Task InitializeAsync()
{
// ...
s_VivoxService = new PresenceVivoxService(s_ServiceHttpClient, s_PresenceManager, s_ServiceHostResolver);
// ...
}
- Initialize the UnityServices at the application level in the
InitializeUnityServicesmethod before doing any call to the IVoiceService.
async Task InitializeUnityServices()
{
if (UnityServices.State != ServicesInitializationState.Uninitialized)
return;
var vivoxInitializationOptions = new InitializationOptions();
vivoxInitializationOptions.SetVivoxCredentials(PresenceVivoxServiceComponents.VivoxServer, PresenceVivoxServiceComponents.VivoxDomain, PresenceVivoxServiceComponents.VivoxIssuer);
await UnityServices.InitializeAsync(vivoxInitializationOptions);
VivoxService.Instance.SetTokenProvider(PresenceVivoxServiceComponents.VivoxTokenProvider);
await VivoxService.Instance.InitializeAsync();
}
- Shut down the services in the
Shutdownmethod.
public static void Shutdown()
{
// ...
s_VivoxService.Dispose();
s_VivoxService = null;
// ...
}
Join and leave voice channels
To join or leave a voice channel, see the following steps:
- In your scene, create Join Voice and Leave Voice buttons.

- Go to GameObject > Create Empty and name the new game object VoiceManager.
- In your
Assets/Scriptsdirectory, create a new script and name itVoiceManager. - Attach the
VoiceManagerscript to your VoiceManager game object. - In your
PresentationManagerscript file, use thePresentationManagerclass to do the following:- Reference an
IVoiceServiceand anISessionProvider - Reference the join and leave buttons
- Store the current session
- Describe whether the participant has joined the voice channel
- Reference an
public class VoiceManager : MonoBehaviour
{
[SerializeField]
Button m_JoinButton;
[SerializeField]
Button m_LeaveButton;
ISessionProvider m_SessionProvider;
IVoiceService m_VoiceService;
ISession m_CurrentSession;
bool m_HasJoined;
}
- Use the
Awakemethod to retrieve services from PlatformServices and to subscribe to theSessionChangedevent and the button clicks. Use theOnDestroymethod to unsubscribe from the events. Requesting the appropriate microphone permissions for the given platform should also be performed onAwake.
void Awake()
{
m_SessionProvider = PlatformServices.SessionProvider;
m_VoiceService = PlatformServices.VoiceService;
m_SessionProvider.SessionChanged += OnSessionChanged;
m_JoinButton.onClick.AddListener(new UnityEngine.Events.UnityAction(OnJoinClicked));
m_LeaveButton.onClick.AddListener(new UnityEngine.Events.UnityAction(OnLeaveClicked));
StartCoroutine(VerifyMicrophoneAuthorization());
}
void OnDestroy()
{
m_SessionProvider.SessionChanged -= OnSessionChanged;
m_JoinButton.onClick.RemoveAllListeners();
m_LeaveButton.onClick.RemoveAllListeners();
}
static IEnumerator VerifyMicrophoneAuthorization()
{
if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
{
yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
Debug.LogError("Microphone access denied. Vivox voice chat will not work.");
}
}
- Use the
OnSessionChangedmethod to clean up any previous sessions and to make sure the buttons are displayed correctly.
async void OnSessionChanged(ISession session)
{
m_JoinButton.interactable = false;
m_LeaveButton.interactable = false;
// Clean up any previous session
if (m_CurrentSession != null && m_HasJoined)
{
await m_VoiceService.LeaveAsync();
}
m_CurrentSession = session;
if (session != null)
{
m_JoinButton.interactable = true;
}
}
- Use the
OnJoinClickedmethod to implement callbacks for the button clicks.
async void OnJoinClicked()
{
m_JoinButton.interactable = false;
await m_VoiceService.JoinAsync();
m_HasJoined = true;
m_LeaveButton.interactable = true;
}
async void OnLeaveClicked()
{
m_LeaveButton.interactable = false;
await m_VoiceService.LeaveAsync();
m_HasJoined = false;
m_JoinButton.interactable = true;
}
(Optional)Display information about a voice channel
To display information about a voice channel, see the following steps:
- In your scene, create a text field to display information about the voice channel.
- In your
Assets/Scriptsdirectory, create a new script and name itVoiceTextUpdater. - Attach the
VoiceTextUpdaterscript to your VoiceManager game object. - In your
VoiceTextUpdaterscript file, use theVoiceTextUpdaterclass to reference anIVoiceServiceand your text field.
public class VoiceTextUpdater : MonoBehaviour
{
[SerializeField]
Text m_TextField;
IVoiceService m_VoiceService;
}
- Use the
Awakemethod to retrieve services from PlatformServices and to subscribe to theVoiceParticipantUpdatedevent. Use theOnDestroymethod to unsubscribe from the event.
void Awake()
{
m_VoiceService = PlatformServices.VoiceService;
m_VoiceService.VoiceParticipantUpdated += ApplyVoiceUpdate;
}
void OnDestroy()
{
m_VoiceService.VoiceParticipantUpdated -= ApplyVoiceUpdate;
}
- Use the
ApplyVoiceUpdatemethod to update the text with information about the voice chat.
void ApplyVoiceUpdate(IEnumerable<IVoiceParticipant> voiceParticipants)
{
if (voiceParticipants != null && voiceParticipants.Any())
{
var sb = new StringBuilder();
foreach (var voiceParticipant in voiceParticipants)
{
sb.AppendLine($"{voiceParticipant.DisplayName} : {voiceParticipant.AudioIntensity}");
}
m_TextField.text = sb.ToString();
}
else
{
m_TextField.text = "No voice participant in the room.";
}
}