This thread helped me alot so thank you to the OP and everyone who has contributed. Google also seems to like it alot too when searching for audio crossfading. If anyone needs āset and forgetā crossfading between two audio sources, I made this snippet:
private bool audioBlendInprogress = false;
//----------------------------------
// AUDIO CROSSFADE
//----------------------------------
private IEnumerator CrossFadeAudio(AudioSource audioSource1, AudioSource audioSource2, float crossFadeTime, float audioSource2VolumeTarget)
{
string debugStart = "<b><color=red>ERROR:</color></b> ";
int maxLoopCount = 1;
int loopCount = 0;
float startAudioSource1Volume = audioSource1.volume;
if(audioSource1 == null || audioSource2 == null)
{
Debug.Log(debugStart + transform.name + ".EngineControler.CrossFadeAudio recieved NULL value.\n*audioSource1=" + audioSource1.ToString() + "\n*audioSource2=" + audioSource2.ToString(), gameObject);
yield return null;
}
else
{
audioBlendInprogress = true;
audioSource2.volume = 0f;
audioSource2.Play();
while ((audioSource1.volume > 0f && audioSource2.volume < audioSource2VolumeTarget) && loopCount < maxLoopCount)
{
audioSource1.volume -= startAudioSource1Volume * Time.deltaTime / crossFadeTime;
audioSource2.volume += audioSource2VolumeTarget * Time.deltaTime / crossFadeTime;
loopCount++;
yield return null;
}
if (loopCount < maxLoopCount)
{
audioSource1.Stop();
audioSource1.volume = startAudioSource1Volume;
audioBlendInprogress = false;
}
else
{
Debug.Log(debugStart + transform.name + ".EngineControler.CrossFadeAudio.loopCount reached max value.\nloopCount=" + loopCount + "\nmaxLoopCount=" + maxLoopCount, gameObject);
}
}
}
It simply takes the two audio sources and fades across the two audio sources. The benefit of this method is that itās āset and forgetā meaning it runs in a coroutine not in Update. Not that itās any better than anything else mentioned here, itās just another option. It also includes a safety switch (loopCount) that should be included in every āwhileā or ādoā statement in my opinion.
Anyways, to call it you would use:
StartCoroutine(CrossFadeAudio(audioSource1, audioSource2, 10f, 1f));
The first parameter āaudioSource1ā is the currently playing audio source.
The second āaudioSource2ā is the audio source to crossfade too.
Third is the time in seconds to do the fade.
Forth is the target volume of audio source 2 (1f = 100%).
Also, the āaudioBlendInprogressā can be used to check if a fade is in progress.
private bool audioBlendInprogress = false;
My real world example of using this method:
private void StartStopEngine()
{
if (audioBlendInprogress == false)
{
if (engineIsRunning == false)
{
audioSource1.clip = engineData.audioEngineStart;
audioSource1.loop = false;
audioSource2.clip = engineData.audioEngineIdle;
audioSource2.pitch = 0.5f;
audioSource2.loop = true;
audioSource1.Play();
StartCoroutine(CrossFadeAudio(audioSource1, audioSource2, 10f, 1f));
engineIsRunning = true;
}
else
{
audioSource1.clip = engineData.audioEngineShutDown;
audioSource1.loop = false;
StartCoroutine(CrossFadeAudio(audioSource2, audioSource1, 3f, 1f));
engineIsRunning = false;
}
}
}
Here I have a audio clip of an engine start and an engine idle. I wanted to play the engine start then crossfade to the idle clip. I first check to see if a crossfade is in progress. Then check if the engine is running. If I made it past that, I then set up the audio sources and start playing the engine start clip. Then I call the āCrossFadeAudio()ā coroutine to fade the audio from engine start, too engine idle.
The āelseā for āengineIsRunningā is to fade between engine idle and the engine shutdown clip. I have a toggle input to start and stop the engines.
I hope this helps someone.
Edit: I noticed I left my debug info in the snippet and was going to remove it. But then decided to leave it in and make it self contained as it may help someone. So the main script may look more complicated than it really is lol ;-).