Hi, here’s another quick demo of some C# code I wrote for Jettomero in Unity3D.
I was just adding some new functionality to my music system and needed to be able to transition volume levels on a given audio source. This is simple to accommodate using a coroutine and I can pass an Audio Source and target volume to a generic function to keep things clean and reusable. However, I needed to be able to call these volume transitions on potentially multiple audio sources at once and also needed to be able to stop any given transition if that audio source received an updated transition call. Fortunately Unity’s StopCoroutine will accept an IEnumerator as an argument so I can set up a reference to every coroutine before I start it and then use that reference to call it to stop later on. Since every audio source would only ever have a single active transition I decided to use a dictionary to store a paired AudioSource and IEnumerator. This way I can easily check the dictionary for an existing transition provided the audio source. Being careful to remove completed transitions from the dictionary again this technique seems to work perfectly for my needs. This code could obviously be adapted for non-audio purposes as well.
Here’s what the code looks like, (remember to add “using System.Collections.Generic” at the top of your .cs script to import the Dictionary support):
Dictionary<AudioSource,IEnumerator> activeTransitions = new Dictionary<AudioSource, IEnumerator>();
void ChangeVolume(AudioSource source, float targetVolume, float transitionTime)
{
if (activeTransitions.ContainsKey(source))
{
IEnumerator activeTransition;
activeTransitions.TryGetValue(source, out activeTransition);
StopCoroutine(activeTransition);
activeTransitions.Remove(source);
}IEnumerator audioTransition = TransitionVolume(source, targetVolume, transitionTime);
StartCoroutine(audioTransition);
activeTransitions.Add(source, audioTransition);
}IEnumerator TransitionVolume(AudioSource source, float targetVolume, float transitionTime)
{
float currentVolume = source.volume;
float progress = 0.0f;
while (progress < 1.0f)
{
progress += Time.deltaTime/transitionTime;
source.volume = Mathf.Lerp(currentVolume, targetVolume, progress);
yield return null;
}
activeTransitions.Remove(source);
}
