# EasyManager.cs

**EasyManager** inherits from **MonoBehaviour** so it can be attached to a GameObject and **inherited** to make your own Custom VivoxManager. **EasyManager is basically a super class/wrapper** for all **EasyCode** functionality. Instead of using EasyManager you can access **EasyCode** functionality directly/separately by injecting necessary classes in your script by using the <mark style="color:blue;">\[Inject]</mark> attribute. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes)

Necessary libraries for **`EasyManager.cs`** to work.  **`namespace`** separate's your project or script from other peoples scripts or libraries that use similar names to avoid compile errors. It also forces people to use a **`using`** statement when they want to use your script or library

```csharp
using EasyCodeForVivox.Events;
using EasyCodeForVivox.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using VivoxUnity;
using Zenject;

namespace EasyCodeForVivox
{

```

Private variables that are set by the **`Initialize()`** method.&#x20;

```csharp
    private EasyLogin _login;
    private EasyChannel _channel;
    private EasyAudioChannel _voiceChannel;
    private EasyTextChannel _textChannel;
    private EasyUsers _users;
    private EasyMessages _messages;
    private EasyMute _mute;
    private EasyTextToSpeech _textToSpeech;
    private EasyAudio _audio;
    private EasySettingsSO _settings;
    private EasyEvents _events;
```

**`Intialize()`** method is used to **Inject and assign** the private variables to any classes **EasyManager** needs to function. Instances are **injected by** **Zenject** dependency injection by using the <mark style="color:blue;">\[Inject]</mark> attribute

```csharp
    [Inject]
    public void Initialize(EasyLogin login, EasyChannel channel, EasyAudioChannel voiceChannel, EasyTextChannel textChannel,
        EasyUsers users, EasyMessages messages, EasyMute mute, EasyTextToSpeech textToSpeech, EasyAudio audio,
        EasySettingsSO settings, EasyEvents events)
    {
        _login = login ?? throw new ArgumentNullException(nameof(login));
        _channel = channel ?? throw new ArgumentNullException(nameof(channel));
        _voiceChannel = voiceChannel ?? throw new ArgumentNullException(nameof(voiceChannel));
        _textChannel = textChannel ?? throw new ArgumentNullException(nameof(textChannel));
        _users = users ?? throw new ArgumentNullException(nameof(users));
        _messages = messages ?? throw new ArgumentNullException(nameof(messages));
        _mute = mute ?? throw new ArgumentNullException(nameof(mute));
        _textToSpeech = textToSpeech ?? throw new ArgumentNullException(nameof(textToSpeech));
        _audio = audio ?? throw new ArgumentNullException(nameof(audio));
        _settings = settings ?? throw new ArgumentNullException(nameof(settings));
        _events = events ?? throw new ArgumentNullException(nameof(events));
    }
```

{% hint style="info" %}
***I have tried to break up bigger methods and explain them in better detail. By clicking the tabs or exapandles you will see more info reated to what each method is doing***
{% endhint %}

**`InitializeClient()`** is used to initialize **Vivox** **Client**, register Dynamic Events, and subscribe to necessary events for EasyCode to work.&#x20;

{% tabs %}
{% tab title="Pre-Processor Directive" %}
A **Pre-Processor Directive** is used to disable logging for builds for faster performance. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/related-info/pre-processor-directives)

```csharp
// disable Debug.Log Statements in the build for better performance
#if UNITY_EDITOR Debug.unityLogger.logEnabled = true; 
#else Debug.unityLogger.logEnabled = false; 
#endif
```

{% endtab %}

{% tab title="Vivox Client" %}
Checks if Vivox Client is Initialized, if not it Initializes it then sets I

```csharp
if (EasySession.Client.Initialized)
            {
                if (_settings.LogEasyManager)
                    Debug.Log($"{nameof(EasyManager)} : Vivox Client is already initialized, skipping...".Color(EasyDebug.Yellow));
                return;
            }
            else
            {
                if (!EasySession.Client.Initialized)
                {
                    EasySession.Client.Uninitialize();
                    EasySession.Client.Initialize(vivoxConfig);
                  // code removed for brevity
                }
            }
```

{% endtab %}

{% tab title="Events" %}
Subscribes to necessary Vivox events for **EasyManager** to work properly

```csharp
_audio.Subscribe(EasySession.Client);
SubscribeToVivoxEvents();
```

{% endtab %}

{% tab title="Dynamic Events" %}
Checks if **Dynamic Events** have been enabled (on be default). You can change this in **`Assets/EasyCodeForVivox/Settings/EasySettings`** scriptable object. [Read more about Dynamic Events here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dynamic-events/dynamic-events). I have left this comment in to remind myself why I am using <mark style="color:blue;">List\<Task></mark> vs <mark style="color:blue;">Parallel.ForEach</mark> vs a single <mark style="color:blue;">Task</mark>

```csharp
if (_settings.UseDynamicEvents)
{
    // may seem redundant to use Task.Run because multiple Tasks are created in DynamicEvents.RegisterEvents()
    // but I tested running DynamicEvents.RegisterEvents() without using Task.Run and it was way slower
    // difference was approximately .900 milliseconds vs .090 milliseconds(results will vary based on how many assemblies are in your project
    // and how many cpu's you have)
    await Task.Run(async () =>
    {
        await DynamicEvents.RegisterEvents(_settings.OnlySearchAssemblyCSharp, _settings.LogAssemblySearches, _settings.LogAllDynamicMethods);
        if (DynamicEvents.Methods.Count == 0)
        {
            _settings.UseDynamicEvents = false;
        }
    });
}
```

{% endtab %}
{% endtabs %}

**`UnitializeClient()`** is used to clean up resources used by Vivox and EasyCode. Also used to subscribe from events to prevent memory leaks

```csharp
    public void UnitializeClient()
    {
        _audio.Unsubscribe(EasySession.Client);
        UnsubscribeToVivoxEvents();
        EasySession.Client.Uninitialize();
    }
```

### Subscribe To Vivox Events

**`SubscribeToVivoxEvents();`** Subscribes to relevant **Vivox** events .&#x20;

```csharp
public void SubscribeToVivoxEvents()
```

### &#x20;Audio Device **Events**

```csharp
EasySession.Client.AudioInputDevices.AvailableDevices.AfterKeyAdded += _audio.OnAudioInputDeviceAdded;
EasySession.Client.AudioInputDevices.AvailableDevices.BeforeKeyRemoved += _audio.OnAudioInputDeviceRemoved;
EasySession.Client.AudioInputDevices.AvailableDevices.AfterValueUpdated += _audio.OnAudioInputDeviceUpdated;

EasySession.Client.AudioOutputDevices.AvailableDevices.AfterKeyAdded += _audio.OnAudioOutputDeviceAdded;
EasySession.Client.AudioOutputDevices.AvailableDevices.BeforeKeyRemoved += _audio.OnAudioOutputDeviceRemoved;
EasySession.Client.AudioOutputDevices.AvailableDevices.AfterValueUpdated += _audio.OnAudioOutputDeviceUpdated;
```

{% tabs %}
{% tab title="Script" %}
Use **`EasySession.cs`** to access **VivoxClient (**<mark style="color:blue;">**Client**</mark>**)** and its **Audio Device** events
{% endtab %}

{% tab title="Events" %}

| **AvailableDevices.AfterKeyAdded**     | Called when a **new Audio device** is detected                                                       |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **AvailableDevices.BeforeKeyRemoved**  | Called when an **Audio device** is removed                                                           |
| **AvailableDevices.AfterValueUpdated** | Called **after the 2 previous events** and is called when a device is **added, removed, or changed** |

{% endtab %}

{% tab title="Callback Methods and Parameters" %}

| OnAudioInputDeviceAdded    | **requires (**&#x6F;bject sender, KeyEventArg keyArg&#x73;**)**                                  |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| OnAudioInputDeviceRemoved  | **requires (**&#x6F;bject sender, KeyEventArg keyArg&#x73;**)**                                  |
| OnAudioInputDeviceUpdated  | **requires (**&#x6F;bject sender, ValueEventArg\<string, IAudioDevice> valueArg&#x73;**)**       |
|                            |                                                                                                  |
| OnAudioOutputDeviceAdded   | **requires (**&#x6F;bject sender, KeyEventArg keyArg&#x73;**)**                                  |
| OnAudioOutputDeviceRemoved | **requires (**&#x6F;bject sender<mark style="color:blue;">,</mark> KeyEventArg keyArg&#x73;**)** |
| OnAudioOutputDeviceUpdated | **requires (**&#x6F;bject sender, ValueEventArg\<string, IAudioDevice> valueArg&#x73;**)**       |
| {% endtab %}               |                                                                                                  |

{% tab title="Use Case" %}
Subscribe to Audio Device events if you want to allow users to change their **Mic / Headphone / Speaker** device settings in game instead of having to exit the game and adjust audio device settings
{% endtab %}
{% endtabs %}

### &#x20; **Login Events**

```csharp
 // Subscribe to Login Related Events
 _events.LoggingIn += OnLoggingIn;
 _events.LoggedIn += OnLoggedIn;
 _events.LoggedIn += OnLoggedInSetup;
 _events.LoggingOut += OnLoggingOut;
 _events.LoggedOut += OnLoggedOut;
 
 _events.LoginAdded += OnLoginAdded;
 _events.LoginRemoved += OnLoginRemoved;
 _events.LoginUpdated += OnLoginUpdated;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Login** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event              | Purpose                                                                               |
| ------------------ | ------------------------------------------------------------------------------------- |
| **`LoggingIn`**    | Called when **Vivox** begins logging in a user                                        |
| **`LoggedIn`**     | Called when **Vivox** successfully logs in a user                                     |
| **`LoggingOut`**   | Called locally and immediately when the **`LogoutOfVivox()`** method is called        |
| **`LoggedOut`**    | Called locally and fires after the **`LogoutOfVivox()`** method is called             |
| **`LoginAdded`**   | Called when a new LoginSession is added to Vivox Client - User Logged In              |
| **`LoginRemoved`** | Called when a new LoginSession is removed to Vivox Client - User Logged out           |
| **`LoginUpdated`** | Called when a new LoginSession values are updated in Vivox Client - User Changed Name |
| {% endtab %}       |                                                                                       |

{% tab title="Callback Methods and Parameters" %}

| Callback Method       | Parameters                                  |
| --------------------- | ------------------------------------------- |
| **`OnLoggingIn`**     | **`requires (ILoginSession loginSession)`** |
| **`OnLoggedIn`**      | **`requires (ILoginSession loginSession)`** |
| **`OnLoggedInSetup`** | **`requires (ILoginSession loginSession)`** |
| **`OnLoggingOut`**    | **`requires (ILoginSession loginSession)`** |
| **`OnLoggedOut`**     | **`requires (ILoginSession loginSession)`** |
| **`OnLoginAdded`**    | **`requires (AccountId accountId)`**        |
| **`OnLoginRemoved`**  | **`requires (AccountId accountId)`**        |
| **`OnLoginUpdated`**  | **`requires (ILoginSession loginSession)`** |
| {% endtab %}          |                                             |

{% tab title="Use Case" %}
Subscribe to **Login** events if you want to perform actions based on each level of logging in or out, you want to offer users the ability to have multiple login sessions at 1 time and keep track of them, or simply want to implement a **`Debug.Log`** statement to ensure the player is logged in successfully.
{% endtab %}
{% endtabs %}

###

### **Channel Events**

```csharp
 // Subscribe to Channel Related Events
_events.ChannelConnecting += OnChannelConnecting;
_events.ChannelConnected += OnChannelConnected;
_events.ChannelDisconnecting += OnChannelDisconnecting;
_events.ChannelDisconnected += OnChannelDisconnected;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Channel** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                      | Purpose                                                                                                   |
| -------------------------- | --------------------------------------------------------------------------------------------------------- |
| **`ChannelConnecting`**    | Called when **Vivox** starts connecting a user to a channel. If the channel doesn't exists one is created |
| **`ChannelConnected`**     | Called when **Vivox** successfully connects a user to a channel.                                          |
| **`ChannelDisconnecting`** | Called when **Vivox** starts disconnecting a user from a channel.                                         |
| **`ChannelDisconnected`**  | Called when **Vivox** successfully disconnects a user from a channel.                                     |
| {% endtab %}               |                                                                                                           |

{% tab title="Callback Methods and Parameters" %}

| Callback Method              | Parameters                                      |
| ---------------------------- | ----------------------------------------------- |
| **`OnChannelConnecting`**    | **`requires (IChannelSession channelSession)`** |
| **`OnChannelConnected`**     | **`requires (IChannelSession channelSession)`** |
| **`OnChannelDisconnecting`** | **`requires (IChannelSession channelSession)`** |
| **`OnChannelDisconnected`**  | **`requires (IChannelSession channelSession)`** |
| {% endtab %}                 |                                                 |

{% tab title="Use Case" %}
Subscribe to Channel events if you want to perform actions based on each level of connecting/disconnecting or simply want to implement a **`Debug.Log`** statement to ensure the player is connected to a channel
{% endtab %}
{% endtabs %}

###

### **Audio Channel Events**

```csharp
 // Subscribe to Channel Related Events
_events.AudioChannelConnecting += OnVoiceConnecting;
_events.AudioChannelConnected += OnVoiceConnected;
_events.AudioChannelDisconnecting += OnVoiceDisconnecting;
_events.AudioChannelDisconnected += OnVoiceDisconnected;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Audio Channel** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                           | Purpose                                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **`VoiceChannelConnecting`**    | Called when **Vivox** starts connecting a user to a voice channel. Channel must exist for voice to connect |
| **`VoiceChannelConnected`**     | Called when **Vivox** successfully connects a user to voice a channel.                                     |
| **`VoiceChannelDisconnecting`** | Called when **Vivox** starts disconnecting a user from a voice channel.                                    |
| **`VoiceChannelDisconnected`**  | Called when **Vivox** successfully disconnects a user from a voice channel.                                |
| {% endtab %}                    |                                                                                                            |

{% tab title="Callback Methods and Parameters" %}

| Callback Method            | Parameters                                      |
| -------------------------- | ----------------------------------------------- |
| **`OnVoiceConnecting`**    | **`requires (IChannelSession channelSession)`** |
| **`OnVoiceConnected`**     | **`requires (IChannelSession channelSession)`** |
| **`OnVoiceDisconnecting`** | **`requires (IChannelSession channelSession)`** |
| **`OnVoiceDisconnected`**  | **`requires (IChannelSession channelSession)`** |
| {% endtab %}               |                                                 |

{% tab title="Use Case" %}
Subscribe to Voice Channel events if you want to perform actions based on each level of connecting/disconnecting or simply want to implement a **`Debug.Log`** statement to ensure the player is connected to a voice channel
{% endtab %}
{% endtabs %}

###

### **Text Channel Events**

```csharp
 // Subscribe to Channel Related Events
 _events.TextChannelConnecting += OnTextChannelConnecting;
 _events.TextChannelConnected += OnTextChannelConnected;
 _events.TextChannelDisconnecting += OnTextChannelDisconnecting;
 _events.TextChannelDisconnected += OnTextChannelDisconnected;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Text Channel** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                          | Purpose                                                                                             |
| ------------------------------ | --------------------------------------------------------------------------------------------------- |
| **`TextChannelConnecting`**    | Called when **Vivox** starts connecting a user to a channel. Channel must exist for text to connect |
| **`TextChannelConnected`**     | Called when **Vivox** successfully connects a user to a text channel.                               |
| **`TextChannelDisconnecting`** | Called when **Vivox** starts disconnecting a user from a text channel.                              |
| **`TextChannelDisconnected`**  | Called when **Vivox** successfully disconnects a user from a text channel.                          |
| {% endtab %}                   |                                                                                                     |

{% tab title="Callback Methods and Parameters" %}

| Callback Method                  | Parameters                                      |
| -------------------------------- | ----------------------------------------------- |
| **`OnTextChannelConnecting`**    | **`requires (IChannelSession channelSession)`** |
| **`OnTextChannelConnected`**     | **`requires (IChannelSession channelSession)`** |
| **`OnTextChannelDisconnecting`** | **`requires (IChannelSession channelSession)`** |
| **`OnTextChannelDisconnected`**  | **`requires (IChannelSession channelSession)`** |
| {% endtab %}                     |                                                 |

{% tab title="Use Case" %}
Subscribe to Text Channel events if you want to perform actions based on each level of connecting/disconnecting or simply want to implement a **`Debug.Log`** statement to ensure the player is connected to a text channel
{% endtab %}
{% endtabs %}

###

### Message Events

```csharp
 // Subscribe to Channel Message Related Events
_events.ChannelMessageRecieved += OnChannelMessageRecieved;
_events.EventMessageRecieved += OnEventMessageRecieved;

 // Subscribe to Direct Message Related Events
 _events.DirectMessageRecieved += OnDirectMessageRecieved;
 _events.DirectMessageFailed += OnDirectMessageFailed;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Channel and Direct message** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                        | Purpose                                                                                               |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| **`ChannelMessageRecieved`** | Called when a channel message is received. The message is passed to the method parameter              |
| **`EventMessageRecieved`**   | Called when a channel event/hidden message is received. The message is passed to the method parameter |
| **`DirectMessageRecieved`**  | Called when a direct message is received. The message is passed to the method parameter               |
| **`DirectMessageFailed`**    | Called when a message has failed to send. The message is passed to the method parameter               |
| {% endtab %}                 |                                                                                                       |

{% tab title="Callback Methods and Parameters" %}

| Callback Methods               | Parameters                                                |
| ------------------------------ | --------------------------------------------------------- |
| **`OnChannelMessageRecieved`** | **`requires (IChannelTextMessage textMessage)`**          |
| **`OnEventMessageRecieved`**   | **`requires (IChannelTextMessage textMessage)`**          |
| **`OnDirectMessageRecieved`**  | **`requires (IDirectedTextMessage directedTextMessage)`** |
| **`OnDirectMessageFailed`**    | **`requires (IFailedDirectedTextMessage failedMessage)`** |
| {% endtab %}                   |                                                           |

{% tab title="Use Case" %}
These Message events are necessary to receive **channel, event/hidden, or direct** messages. **Event/Hidden** messages can be used if you (very useful if you are not using a Networking Stack) want to pass info to players in the channel. When a message fails to send you can use the **OnDirectMessageFailed** callback to store the message or try and resend it.
{% endtab %}
{% endtabs %}

###

### User Events

The keywords **Fire** and **Called** are used interchangeably

```csharp
_events.UserJoinedChannel += OnUserJoinedChannel;
_events.UserLeftChannel += OnUserLeftChannel;
_events.UserValuesUpdated += OnUserValuesUpdated;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **User** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                   | Purpose                                                                                                                                                                                                                                                  |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`UserJoinedChannel`** | Called when a user joins a channel. This event will fire for every user that is in the same channel                                                                                                                                                      |
| **`UserLeftChannel`**   | Called when a user leaves a channel. This event will fire for every user that is in the same channel                                                                                                                                                     |
| **`UserValuesUpdated`** | Called when a user values are updated in a channel such as speaking, muted, name change. This event will fire for every user that is in the same channel. This event is called many times by Vivox implement at your own peril :grimacing: . You can set |
| {% endtab %}            |                                                                                                                                                                                                                                                          |

{% tab title="Callback Methods and Parameters" %}

| Callback Methods                | Parameters                                |
| ------------------------------- | ----------------------------------------- |
| **`OnParticipantAdded`**        | **`requires (IParticipant participant)`** |
| **`OnParticipantRemoved`**      | **`requires (IParticipant participant)`** |
| **`OnParticipantValueUpdated`** | **`requires (IParticipant participant)`** |
| {% endtab %}                    |                                           |

{% tab title="Use Case" %}
If you want to know if a user has joined or left a channel
{% endtab %}
{% endtabs %}

```csharp
_events.UserMuted += OnUserMuted;
_events.UserUnmuted += OnUserUnmuted;
_events.UserSpeaking += OnUserSpeaking;
_events.UserNotSpeaking += OnUserNotSpeaking;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **User** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                 | Purpose                                  |
| --------------------- | ---------------------------------------- |
| **`UserMuted`**       | Called when a user is muted              |
| **`UserUnmuted`**     | Called when a user is unmuted            |
| **`UserSpeaking`**    | Called when a user is speaking           |
| **`UserNotSpeaking`** | Called when a user is no longer speaking |
|                       |                                          |
| {% endtab %}          |                                          |

{% tab title="Callback Methods and Parameters" %}

| Callback Method         | Parameters                                |
| ----------------------- | ----------------------------------------- |
| **`OnUserMuted`**       | **`requires (IParticipant participant)`** |
| **`OnUserUnmuted`**     | **`requires (IParticipant participant)`** |
| **`OnUserSpeaking`**    | **`requires (IParticipant participant)`** |
| **`OnUserNotSpeaking`** | **`requires (IParticipant participant)`** |
| {% endtab %}            |                                           |

{% tab title="Use Case" %}
If you want to know if a player is speaking or muted to update your UI with a different image for each event.
{% endtab %}
{% endtabs %}

### Text To Speech ( TTS ) Events

```csharp
 // Subscribe to Text-To-Speech related events
 _events.TTSMessageAdded += OnTTSMessageAdded;
 _events.TTSMessageRemoved += OnTTSMessageRemoved;
 _events.TTSMessageUpdated += OnTTSMessageUpdated;
```

{% tabs %}
{% tab title="Script" %}
Uses **`EasyEvents.cs`** to access **Text-To-Speech** events

You can also access **EasyEvents** by injecting it into your class using Zenject dependency injection. [Read more about it here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection).
{% endtab %}

{% tab title="Events" %}

| Event                   | Purpose                                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| **`TTSMessageAdded`**   | Called when a message is spoken or added to the TTS queue.                                        |
| **`TTSMessageRemoved`** | Called when a message is removed from the TTS queue.                                              |
| **`TTSMessageUpdated`** | Called when a message is spoken, overridden, removed, added to the TTS queue or TTS voice changed |
| {% endtab %}            |                                                                                                   |

{% tab title="Callback Methods and Parameters" %}

|                           |                                                    |
| ------------------------- | -------------------------------------------------- |
| **`OnTTSMessageAdded`**   | **`requires (ITTSMessageQueueEventArgs ttsArgs)`** |
| **`OnTTSMessageRemoved`** | **`requires (ITTSMessageQueueEventArgs ttsArgs)`** |
| **`OnTTSMessageUpdated`** | **`requires (ITTSMessageQueueEventArgs ttsArgs)`** |
| {% endtab %}              |                                                    |

{% tab title="Use Case" %}
If you want to keep a log of all messages sent thru TTS for accessibility reasons or send notifications to the user using TTS when their message is done playing or wants to send message after hearing it first
{% endtab %}
{% endtabs %}

### **Unsubscribe From Vivox Events**

**`UnsubscribeToVivoxEvents()`** unsubscribes from all the events explained above. Refer to explanations above for each category. This is called on **`OnApplicationQuit()`** in **Unity**
