> For the complete documentation index, see [llms.txt](https://akila.gitbook.io/fps-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://akila.gitbook.io/fps-framework/tutorials/systems/audio-system.md).

# Audio System

The audio system is powered by the **Audio** class and the **Audio Profile**, which together handle all the audio logic.

* **Audio Profile**: This holds all the data related to the sounds you're working with, such as audio clips, settings, and configuration.
* **Audio Class**: This class is responsible for playing and adjusting sounds based on the data in the **Audio Profile**, ensuring the correct audio is played and modified according to the game’s events.

## Creating An Audio Profile

To begin, create an **Audio Profile** which contains all the necessary data for the audio to be played:

1. **Create the Audio Profile**\
   Right-click in the Project window, then navigate to **`Create > Akila > FPS Framework > Audio Profile`**.
2. **Modify the Profile**\
   This will create a new Audio Profile that you can now modify to define the audio clips and settings for your sounds. Adjust the data within the profile to suit your specific audio needs.

<figure><img src="/files/8nNBIyRRhUumUwIrL739" alt=""><figcaption></figcaption></figure>

The **Audio Profile** is similar to the default **Audio Source** fields but comes with additional features that make it more versatile and tailored for advanced audio control. These extra features include:

* **Audio Layers**: Allows you to categorize and organize different sound effects based on layers, giving you more control over which sounds are played and when.
* **Enhanced 3D Sound**: Offers more detailed 3D sound controls, ensuring that audio behaves more naturally in a 3D space, such as adjusting sound attenuation and positioning.
* **Additional Small Features**: Includes other subtle adjustments and settings to fine-tune how audio is played, providing a richer and more dynamic sound experience.

These enhancements make the **Audio Profile** a valuable tool for more complex audio setups in your project.

### 6D Sounds

**6D Sounds** are an advanced form of directional audio that enhances how sounds are perceived based on the listener’s orientation. Unlike standard 3D audio, 6D sound modifies the pitch depending on the direction the sound is coming from—forward, backward, right, left, up, or down.

All pitch values for each direction can be customized under the **6D Sound Settings** section, allowing you to fine-tune how the audio behaves and sounds from every angle, creating a more immersive and spatially aware audio experience.

<figure><img src="/files/Fomz13noPgL3n8cAkDqE" alt=""><figcaption></figcaption></figure>

A value of **0.1** in any of the **6D Sound Settings** adds **0.1** to the pitch when the sound originates from that specific direction. For example, if the sound is playing from behind the audio listener and the **Backward** factor is set to **0.1**, the pitch will increase from **1.0** to **1.1** during playback. This directional pitch adjustment enhances spatial perception, making audio feel more dynamic and context-aware.

### Audio Layering

**Audio Layers** are essentially additional audio clips that play after a specific delay when the main audio is triggered. This feature is particularly useful for sounds that need to occur in sequence, such as reloading sounds, footsteps, or any other layered audio effects.

For example, you can play a main sound (like a gunshot) and, using audio layers, trigger a secondary sound (like a reload or click) to play shortly after, enhancing the realism and depth of the audio experience.

<figure><img src="/files/JinqXIsAvtvpixgqIBHq" alt=""><figcaption></figcaption></figure>

As shown in the screenshot, each element in **Audio Layers** consists of two fields:

* **Time**: Specifies the delay (in seconds) after the main audio is played, determining when this layered sound will trigger.
* **Audio Clip**: The specific audio clip to be played at the defined time.

This setup allows you to sequence sounds with precise timing, making complex audio events like weapon reloads or machinery sounds easy to manage and more immersive.

## Playing Audio

There are two main ways to play audio using the data from an **Audio Profile**:

### Audio Emitter

The **Audio Emitter** component functions similarly to a standard **Audio Source**, but instead of using an **Audio Clip**, it uses an **Audio Profile**. This allows it to leverage all the advanced features of the audio system, such as audio layers and 6D sound, making it ideal for quick and flexible audio setups. Simply attach the Audio Emitter to a GameObject, assign an Audio Profile, and you're ready to play sound with enhanced control.

<figure><img src="/files/qFuV5w0KaRupJAOCM8Rd" alt=""><figcaption></figcaption></figure>

Assign your **Audio Profile** to the **Audio Profile** field in the **Audio Emitter** component. Then, either enable **Play On Awake** to have the sound play automatically when the scene starts, or manually trigger it by calling `AudioEmitter.Play()` in your script.

### Audio Setup (New)

To use the audio system programmatically, you'll need a custom script. Start by creating a new C# script, then include the necessary namespace at the top:

```csharp
using Akila.FPSFramework;
```

This gives you access to the framework’s audio tools, such as `Audio`, `AudioEmitter`, and `AudioProfile`. You can now implement audio logic using the system's features.

Next, define the fields for your Audio Profile and the Audio class:

```csharp
//Make sure to initialize Audio to avoid null ref errors.
public Audio myAudio = new Audio();
```

Audio will appear in the inspector as AudioProfile field in which you assgin your sound to be played. Then in code, myAudio.Play() is called to play this sound. The purpose is to make things less messy and better to handle.

Before playing, it needs to be setup:

```csharp
public Audio myAudio;

private void Start()
{
   //Setup here:
   myAudio.Setup(gameObject);
}
```

This lets your audio know about where to play this audio, without it it won't work.

To play a sound, stop or pause call myAudio.Play() or myAudio.Stop() or my Audio.Pause() etc...

#### Using a scriptable object?

In case you are using a scriptable object to store sounds and want to still be able to play your sounds, you would take a little bit diffrent approach. In your scriptable object, all sounds should be of type Audio, like this:

```csharp
public class MyAudioData : ScriptableObject
{
    public Audio jumpSound;
    public Audio landSound;
    //All your sounds are of type Audio.
}
```

Then in your Monobehaviour class, you would instead use SetupFrom() method instead of Setup(), like this:

```csharp
public class MyBehaviour : Monobehaviour
{
   public MyAudioData audioData;
   
   //Local fields for jump and land, so that in case
//this class is used in multiple instances, when each is independent and not in the SO itself
   private Audio jumpSFX = new Audio();
   private Audio landSFX = new Audio();
   
   private void Start()
   {
      //SetupFrom() has 2 parameters, 
      // 1- GameObject obj -> the object this script is attached to
      // 2- Audio audioToCopy -> the audio to copy that isn't jumpSFX e.g preset.JumpSound
      jumpSFX.SetupFrom(gameObject, audioData.jumpSound);
      landSFX.SetupFrom(gameObject, audioData.landSound);
   }
}
```

This way the sounds are independent from your scriptable object. SetupFrom copies the assigned audio profile in the audioToCopy parameter to your Audio then sets it up for cleaner and easier setup.

### Audio Setup (Old)

{% hint style="info" %}
The code below belongs to versions 2.2.3 and below. Starting from 2.2.4 the audio system received some bigger changes.
{% endhint %}

To use the audio system programmatically, you'll need a custom script. Start by creating a new C# script, then include the necessary namespace at the top:

```csharp
using Akila.FPSFramework;
```

This gives you access to the framework’s audio tools, such as `Audio`, `AudioEmitter`, and `AudioProfile`. You can now implement audio logic using the system's features.

Next, define the fields for your Audio Profile and the Audio class:

```csharp
// Assignable Audio Profile
public AudioProfile audioProfile;

// Playable audio (handles playback and logic)
private Audio _audio;
```

This setup lets you assign an audio profile from the inspector and use the `Audio` class to control playback in your script.

In the `Start` or `Awake` method, initialize the `_audio` field like this:

```csharp
// Initialize the Audio class
_audio = new Audio();

// Call Setup to add an AudioSource and begin playback
_audio.Setup(this, audioProfile);
```

This sets up the audio system with the assigned profile and prepares it for playback.

This way the audio class is setup and is ready to be played. Call `_audio.Play`or `_audio.PlayOneShot()`
