Fading the background music to make narration more audible

I’m making a game with a decent amount of snarky voice over triggered during gameplay (think ultra-budget Portal). I also have a fairly rockn’ sound track (as in loud, not necessarily “good”). The soundtrack and dialog fight with each other, and often the soundtrack wins. It’s pretty clear I need to “duck” (fade) the background music before playing the narration tracks, and then bring it back up to regular volume afterwards.

So what I want is an ultra-simple two-channel sound system where music (and other sound effects) get quiet when the vocal track is played. Code based or whatever, but preferably free (see ultra-budget comments above).

One dead simple option would be the Duck Volume Audio effect as seen here https://www.youtube.com/watch?v=UJYN4_jUIQs and occasionally mentioned in this forum, but at least as set up in that video it’s actually kind of doing the opposite of what I want - only when the dialog gets loud enough does it compress the music track. But really it should be the other way around - only when the music is loud enough should it be compressed. If the music happens to be calm it can be played at the regular volume level. Also, and really more importantly because it’s calculated dynamically the volume of the music only gets ducked after some dialog gets played. It would be better if the music started to fade out in anticipation of the dialog or at least simultaneously, not after the fact.

It’s not completely beyond my skill level to write some scripts from scratch to do this but it seems like wasted effort and hours given that this can’t be that unusual a requirement.

There’s a lot of details to how ducking is done… honestly I’d just write it. Maybe the Audio Mixer can help support it? I dunno, haven’t used the mixer much.

The deal is to just have a ducking control on the music… you set ducked true/false, and the music steadily goes to the desired volume.

The actual “play voiceover” would be a coroutine that would set the audio to ducked, wait a short period, play the voiceover, then set the audio to not be ducked. It’s not much more than that. I’m usually allergic to coroutines but might be easiest to use one only to sequence the duck-play-unduck part. Or just use a float timer, either way.

Do not use coroutines to actually do the ducking. Just move the volume smoothly down/up based on the duck flag, like this:

Smoothing movement between any two particular values:

You have currentQuantity and desiredQuantity.

  • only set desiredQuantity
  • the code always moves currentQuantity towards desiredQuantity
  • read currentQuantity for the smoothed value

Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

The code: SmoothMovement.cs · GitHub

Seems like using Update() would make the change framerate dependent, at least in terms of step size (probably ok, though). Why not fixedupdate instead?

FixedUpdate() should ONLY ever be used for physics, and used as little as possible.

Update() is the one to use, and use Time.deltaTime to scale your changes appropriately.

You will see this clearly in the above code whenever you get a chance to look at it. :slight_smile: