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:
- Add five AudioSource components to the AudioManager GameObject (one per track type: melody, bass, atmosphere, drums, stinger).
- Drag the WAV files for the starting state into each AudioSource's AudioClip field.
- Set each AudioSource: Play On Awake = false, Loop = true (except stingers).
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
- Add a stinger: Mowjera scores include a stinger track — a short musical accent that fires once on state transition (e.g., a victory fanfare). Wire it to trigger on
OnEnemyDefeated. - Use intensity layering: Some scores have intensity variants (Combat-Low, Combat-High) that respond to a 0–1 intensity parameter instead of named states. Call
AudioManager.Instance.SetIntensity(0.8f)to use them. - Test with headphones: Adaptive music's effect is much more obvious on headphones. A transition that "feels smooth" on laptop speakers might have an audible seam that headphones reveal.
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#.