# Voices

## Overview

The **Voices** module makes it easy to organize and make use of multiple styles of audio (voices) which all aim to communicate the same message (lines), often in various ways (emotions).

While this module can easily be used in many other ways, the original intent is for projects where players can choose the voice of their character(s), or many NPCs say very similar lines. With a special naming convention applied to your `AudioClip` files, the module will automatically set up the entire storage structure and populate the clips in the proper fields.

From there, you simply need to assign a `Voice` object to your player or other character, and create a `Speak(string line)` method to hear the `AudioClip`.

### Naming Convention for Auto Population

The object can auto-populate based on the `AudioClips` in a folder.

To use the auto populate feature, each `AudioClip` should be named appropriately using this convention:

`[VoiceName]_[LineName]_[EmotionName]_[UniqueString]`

Only the first two name segments are required. Emotion and the unique string are both optional.

{% tabs %}
{% tab title="Voices.cs" %}

```csharp
public List<Voice> voices = new List<Voice>();
public List<string> types = new List<string>(); 

public List<string> lineNames = new List<string>(); 
public List<string> emotionNames = new List<string>();
```

{% endtab %}

{% tab title="Voice.cs" %}

```csharp
public string voice; 
public string type;
public List<Line> lines = new List<Line>(); 
```

{% endtab %}

{% tab title="Line.cs" %}

```csharp
public string line; 
public List<AudioClip> audioClip = new List<AudioClip>(); 
public List<Emotion> emotions = new List<Emotion>();
```

{% endtab %}

{% tab title="Emotion.cs" %}

```csharp
public string emotion;
public List<AudioClip> audioClip = new List<AudioClip>();
```

{% endtab %}
{% endtabs %}

## Setup

Create a new folder called `/Voices` or something similar in your project. Right-click and select:

`/Create/Game Modules/Create/Voices`

This will create an `Voices` Scriptable Object in your project. Select that and view the Inspector to begin setting up your data. You can rename this object if you'd like. You can also have multiple `Voices` objects in your project as well.

<figure><img src="/files/mWqcRufbvgz2sC5hApt7" alt=""><figcaption><p>These are the lines the "NPC1" character has in the <strong>Party Based RPG demo game</strong>.</p></figcaption></figure>

Any character which can speak, or object which will have a "voice" from the `Voices` module, should have a `Voice` object on it. See the `VoicesDemoPlayer` class for an example:

```csharp
[Header("Voice")]
public Voice voice;

// The code below is on DemoActor.cs in the Party Based RPG demo game.

/*
* The "Voice" module uses a Voice object which is not serialized, so we store the voiceName as well. Then, when
* Voice is called, we return the _voice field if it is not null -- if it is, then we grab the Voice object
* from the gameData, which has a reference to all of the Voice objects. SetVoice() can be used to specifically
* set the value as well, and replace voiceName with a new name.
*/
private Voice _voice;
[SerializeField] private string voiceName;
public Voice Voice => _voice ??= GameData.gameData.voices.GetVoice(voiceName);
public void SetVoice(Voice value)
{
    _voice = value;
    voiceName = value.voice;
}
```

Your **game controller,** if you have one, or other object, can set the value of `voice` in various ways. View the `VoicesDemoControl` class for an example in our demo scene:

```csharp
public Voices voices; // Populated in the Inspector.

public List<VoicesDemoPlayer> players = new List<VoicesDemoPlayer>();

void Start() => RandomizeVoices();
    
private void RandomizeVoices()
{
    foreach (VoicesDemoPlayer player in players)
    {
        player.voice = voices.GetRandomVoice();
        player.voiceIndex = voices.GetVoiceIndex(player.voice.voice);
    }
}

// You can also assign a specific voice:
private void AssignVoice(VoicesDemoPlayer player, string voiceName)
{
    player.voice = voices.GetVoice(voiceName);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://infinitypbr.gitbook.io/magic-pig-games/game-modules-4/module-documentation/voices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
