Unity 将 AudioSource 的音量降低到 0.01 有效,但将其降低到 1.0 会导致源中断

Unity Lerping the volume of an AudioSource to 0.01 works but lerping it back to 1.0 causes the source to break

不幸的是,我制作的这个音频淡化功能遇到了障碍。它接收源、持续时间和新剪辑。它应该淡出初始剪辑,替换剪辑并将音量调回 1。

public static IEnumerator FadeSwitchAudio(AudioSource audioSource, float duration, int clip)
{
    float firstTimer = 0;
    float secondTimer = 0;
    float start = audioSource.volume;

    // Fade audio out, works as intended 
    while (firstTimer < duration)
    {
        firstTimer += Time.deltaTime;
        audioSource.volume = Mathf.Lerp(start, 0.01f, firstTimer / duration);
        yield return null;
    }

    audioSource.clip = GameObject.FindWithTag("AudioManager").GetComponent<AudioManager>().clips[clip];

    // Fade audio back in, volume jumps immediately to 1 and audiosource stops having output
    yield return new WaitForSeconds(0.1f);
    while (secondTimer < duration)
    {
        secondTimer += Time.deltaTime;
        audioSource.volume = Mathf.Lerp(start, 1.0f, secondTimer / duration);
        yield return null;
    }
}

我尝试了很多不同的定时器功能,但是,似乎增加音频源的音量总是会破坏它。有没有确定的方法可以在不完全失去输出的情况下缓慢增加源的音频?这是检查器中当前行为的 gif。请原谅低分辨率,但你可以看到行为。

Unity Audio Lerping Issue

感谢您的宝贵时间!

这里有两个问题:

  • 仅更改 AudioSource.clip 没有任何作用。

    Assigning clip with a new audio clip does not instantly change the clip that is being played

    您还需要使用 AudioSource.Play 开始播放该新剪辑。

  • 也作为第二个循环的新start,你不想使用你存储在的原始AudioSource.volume Corouinte 的顶部,而不是淡出后的当前版本。

所以只是稍微编辑一下我会使用例如

private const float FADED_OUT_VOLUME = 0.01f;

public static IEnumerator FadeSwitchAudio(AudioSource audioSource, float duration, int clip)
{
    var originalVolume = audioSource.volume;

    // I prefer using for loops over while to eliminate the danger of infinite loops
    // and the need for "external" variables
    // I personally also find this better to read and maintain
    for(var timePassed = 0f; timePassed < duration; timePassed += Time.deltaTime)
    {
        audioSource.volume = Mathf.Lerp(originalVolume, FADED_OUT_VOLUME, timePassed / duration);

        yield return null;
    }

    // To be sure to end with clean values
    audioSource.volume = FADED_OUT_VOLUME;

    // If there is only one instance of `AudioManager` in your scene this is more efficient
    // in general you should fetch that AudioManager reference only ONCE and re-use it
    audioSource.clip = FindObjectOfType<AudioManager>().clips[clip];
    //audioSource.clip = GameObject.FindWithTag("AudioManager").GetComponent<AudioManager>().clips[clip];

    yield return new WaitForSeconds(0.1f);

    // Actually start playing the new clip
    audioSource.Play();

    for(var timePassed = 0f; timePassed < duration; timePassed += Time.deltaTime)
    {
        audioSource.volume = Mathf.Lerp(FADED_OUT_VOLUME, originalVolume, timePassed / duration);

        yield return null;
    }

    audioSource.volume = 1f;
}