← All posts

How to Add Adaptive Music to Your Unity Game

· 5 min read

How to Add Adaptive Music to Your Unity Game

Adaptive music — music that shifts with gameplay — is one of the most powerful tools in a game designer's toolkit. Games like Hades, Ori, and Dead Cells use it to make every moment feel intentional. The problem: the standard tools for implementing it (Wwise, FMOD) have steep learning curves and licensing costs that are hard to justify for solo developers and small studios.

This guide shows you how to add adaptive music to a Unity game from scratch, using Mowjera's exported AudioManager — no middleware required.


What is adaptive music?

Adaptive music changes in real time based on what's happening in your game. Instead of a single looping track, you have several musical states — typically named things like "Explore," "Combat," "Tension," and "Victory" — that crossfade between each other when the player's situation changes.

The musical result: a player walking into a dangerous area hears the music tighten before the enemy even appears. A player clearing a tough fight hears the music lift into triumph the moment the last enemy dies. The music and the gameplay become one experience instead of two things running in parallel.


Step 1: Compose or download an adaptive score

For adaptive music to work, you need a score that's already structured as multiple states. You have two options:

Option A — Compose your own in Mowjera: The browser-based composer lets you define game states (drag-and-drop), write notes in a piano roll, set crossfade triggers, and preview the whole system in real time. Free accounts can compose and export.

Option B — Download from the marketplace: Mowjera's marketplace has scores pre-organized for RPG, Action, Horror, Puzzle, Platformer, and Ambient games. Every score includes the Unity export bundle.

For this tutorial, we'll use an Action genre score with five states: Menu, Explore, Tension, Combat, and Victory.


Step 2: Download the Unity export bundle

From any score's detail page, click Get bundle (or Download Stems if you own a license). The ZIP contains:

Mowjera_MyScore/
  README.txt
  CREDITS.txt
  metadata.json
  unity/
    AudioManager.cs       ← drop this into your Assets/Scripts folder
    Mowjera_README.txt
  stems/
    Menu_melody.wav
    Menu_bass.wav
    Menu_atmosphere.wav
    Combat_melody.wav
    Combat_bass.wav
    Combat_atmosphere.wav
    ... (one WAV per track per state)

Step 3: Import into Unity

1. Create a folder in your Unity project: Assets/Music/MyScore/ 2. Copy all files from the ZIP's stems/ folder into that folder. 3. Copy unity/AudioManager.cs into Assets/Scripts/. 4. In Unity's Project window, select all your WAV files and set their import settings: - Load Type: Streaming (for large files) or Decompress On Load (for small files) - Compression Format: Vorbis (quality 70 is fine for game audio) 5. Create an empty GameObject in your scene, name it AudioManager. 6. Add the AudioManager component to it.


Step 4: Wire up the AudioSources

The exported AudioManager expects AudioSource components for each track. In the Inspector:

The AudioManager will swap clips and fade volumes between them as states change.


Step 5: Call TransitionTo from your game code

The exported AudioManager exposes a single method:

AudioManager.Instance.TransitionTo("Combat");

Call it whenever your game state changes:

// In your enemy AI or game manager:
void OnPlayerDetected() {
    AudioManager.Instance.TransitionTo("Combat");
}

void OnEnemyDefeated() {
    if (AllEnemiesDead()) {
        AudioManager.Instance.TransitionTo("Victory");
    }
}

void OnPlayerEntersSafeZone() {
    AudioManager.Instance.TransitionTo("Explore");
}

The AudioManager handles the crossfade — fading out the current state's tracks and fading in the new state's tracks over the crossfade time you set in Mowjera (default: next bar boundary at the score's BPM).


Step 6: Adjust crossfade timing (optional)

The exported AudioManager has a crossfadeDuration field you can tweak in the Inspector. A lower value (0.5–1s) feels more reactive; a higher value (2–4s) feels more cinematic. The Mowjera editor lets you set this per-transition ("immediate," "next bar," "next phrase") before export, but you can also override it at runtime.


Common mistakes

Playing all clips at once (no fading): Make sure only one set of clips (one state) is audible at any time. The AudioManager handles this automatically, but if you're building a custom solution, you need to track which state is active.

Stem timing desync: WAV stems exported from Mowjera are sample-accurate loops at the same BPM. They'll stay in sync as long as you start them at the same sample position. The AudioManager handles this via AudioSettings.dspTime — don't replace it with a simple Play() call.

Loop length mismatch: If your stems are 32 beats at 120 BPM, they loop every 16 seconds. If you transition mid-loop, the music continues from the same position in the new state (same bar, same beat). This is the "seamless" in seamless crossfade.


Next steps

The score structure — multiple named states, crossfade triggers, stems that stay in sync — is the product. Once you have that structure, the Unity wiring is twenty lines of C#.

Share

Hear it instead of reading about it

Every score on the marketplace plays live in your browser — and the ✨ AI composer drafts an adaptive score from one sentence.

Browse the marketplace