**Subject:** Music doesn't fade back in after the first interaction (Issue with Fade-In)

Hello everyone,

I’m facing an issue with the background music in my game. The music correctly fades out during the first interaction (using FadeOutMusic()), and then it fades back in after the dialogue ends (using FadeInMusic()).

However, the fade-in effect doesn’t work after the first interaction. Once the dialogue is finished and the music is supposed to get louder, it stays loud even if I trigger the interaction again (Action 2 to 3). The fade-in effect doesn’t trigger in these cases.

I’ve already checked if the music source is being correctly referenced and whether the FadeInMusicCoroutine is restarted after the first interaction. But the code doesn’t work as expected anymore.

Here is the part of my code that controls the fade-in and fade-out of the music:


private IEnumerator FadeInMusic()
{
    if (isInRange == false && DialogueFinished == true)
    {
        backgroundMusicScriptRef.audioSource.volume = 0;

        while (backgroundMusicScriptRef.audioSource.volume < 1)
        {
            backgroundMusicScriptRef.audioSource.volume += Time.fixedDeltaTime / backgroundMusicScriptRef.dearceseOrIncreaseVolume;
            yield return null;
        }
    }

    backgroundMusicScriptRef.audioSource.volume = 1;
}

And here is the full code I am currently using:



using UnityEngine;
using Ink.Runtime;
using TMPro;
using UnityEngine.UI;
using System.Collections;

public class TriggerDialogue : MonoBehaviour
{
    [Header("Important References")]
    [SerializeField] private GameObject VisuellQue;
    [SerializeField] private TextAsset inkJSONAsset; // Linked Ink file
    [SerializeField] private TextMeshProUGUI uiText; // Text field for the dialogue
    [SerializeField] private Image DeggerImage;
    [SerializeField] private TextMeshProUGUI ImageDeggerText; // Name in the panel
    [SerializeField] private Canvas DeggerCanvas; // Canvas with text
    private PlayerMovement PlayerMovementScriptRef;

    private BackgroundMusic backgroundMusicScriptRef; 
    private Story story; // Ink story object
    
    [Header("Dialogue Settings")]
    private bool isInRange = false;
    public bool DialogueFinished;
    [SerializeField] private float dialogueCooldown;
    [SerializeField] private float wordDelay = 0.05f; // Delay between words

    private bool isTyping = false; // Whether the text is currently being typed
    private Coroutine typingCoroutine;
    private Coroutine FadeInMusicCoroutine;


    void Start()
    {
        InitializeVariables();
    }

    void Update()
    {
        HandleDialogueInput();
        HandleDialogueCompletion();
        HandleTypingMusicFade();
    }

    #region Initialization

    private void InitializeVariables()
    {
        DialogueFinished = false;

        SetInitialVisibility();

        if (inkJSONAsset != null)
            story = new Story(inkJSONAsset.text);
        else
            Debug.LogError("Ink file is missing! Please link it in the inspector.");

        if (uiText != null)
            uiText.text = "";
        else
            Debug.LogError("UI text field is missing! Please link it in the inspector.");

        if (DeggerCanvas != null)
            DeggerCanvas.gameObject.SetActive(false);

        backgroundMusicScriptRef = FindFirstObjectByType<BackgroundMusic>();
        PlayerMovementScriptRef = FindFirstObjectByType<PlayerMovement>();
    }

    private void SetInitialVisibility()
    {
        if (VisuellQue != null)
            VisuellQue.SetActive(false);

        if (DeggerImage != null)
            DeggerImage.gameObject.SetActive(false);
    }

    #endregion

    #region Dialogue Control

    private void HandleDialogueInput()
    {
        if (isInRange && Input.GetKeyDown(KeyCode.E) && !DialogueFinished)
        {
            if (isTyping)
            {   
                StopCoroutine(typingCoroutine);
                uiText.text = story.currentText; // Show the full text immediately
                isTyping = false;
            }
            else
            {
                DisplayNextLine();
            }

            DisablePlayerMovement();
            ShowDialogueUI();
        }
    }

    private void HandleDialogueCompletion()
    {
        if (DialogueFinished)
        {
            HideDialogueUI();
            EnablePlayerMovement();
        }
    }

    private void HandleTypingMusicFade()
    {
        if (isTyping && backgroundMusicScriptRef != null)
        {
            StartCoroutine(FadeOutMusic());
        }
    }

    private void DisplayNextLine()
    {
        if (story != null && story.canContinue && ImageDeggerText != null)
        {
            if (typingCoroutine != null)
                StopCoroutine(typingCoroutine);

            typingCoroutine = StartCoroutine(TypeText(story.Continue()));
            ImageDeggerText.text = "Degger";
        }
        else
        {
            uiText.text = "";
            DialogueFinished = true;
            StartCoroutine(AllowDialogueAgain());
        }
    }

    private IEnumerator TypeText(string text)
    {
        isTyping = true;
        uiText.text = "";

        foreach (char letter in text.ToCharArray())
        {
            uiText.text += letter;
            yield return new WaitForSeconds(wordDelay);
        }

        isTyping = false;
    }

    #endregion

    #region Player Control

    private void DisablePlayerMovement()
    {
        PlayerMovement.isWalkingAllowed = false;
        PlayerMovement.allowJump = false;
        PlayerMovementScriptRef.isDashAllowed = false;
        PlayerMovement.playerRigidbody.linearVelocity = Vector2.zero;
    }

    private void EnablePlayerMovement()
    {
        PlayerMovement.isWalkingAllowed = true;
        PlayerMovement.allowJump = true;
        PlayerMovementScriptRef.isDashAllowed = true;
    }

    private void ShowDialogueUI()
    {
        if (DeggerCanvas != null)
            DeggerCanvas.gameObject.SetActive(true);

        if (DeggerImage != null)
            DeggerImage.gameObject.SetActive(true);
    }

    private void HideDialogueUI()
    {
        if (DeggerCanvas != null)
            DeggerCanvas.gameObject.SetActive(false);

        if (DeggerImage != null)
            DeggerImage.gameObject.SetActive(false);
    }

    #endregion

    #region Triggers Control

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            isInRange = true;
            if (VisuellQue != null)
                VisuellQue.SetActive(true);
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            isInRange = false;
            if (VisuellQue != null)
                VisuellQue.SetActive(false);

            if (uiText != null)
                uiText.text = "";

            HideDialogueUI();

            if (FadeInMusicCoroutine == null)
            {
                FadeInMusicCoroutine = StartCoroutine(FadeInMusic());
            }
        }
    }

    #endregion

    #region IEnumerator Allow Dialogue Again

    private IEnumerator AllowDialogueAgain()
    {
        yield return new WaitForSeconds(dialogueCooldown);

        if (DialogueFinished)
        {
            DialogueFinished = false;
            if (story != null)
                story.ResetState();
        }
    }

    private IEnumerator FadeOutMusic()
    {
        float startVolume = backgroundMusicScriptRef.audioSource.volume;

        while (backgroundMusicScriptRef.audioSource.volume > 0)
        {
            backgroundMusicScriptRef.audioSource.volume -= startVolume * Time.deltaTime / backgroundMusicScriptRef.dearceseOrIncreaseVolume;
            yield return null;
        }

        backgroundMusicScriptRef.audioSource.volume = 0;
    }

    private IEnumerator FadeInMusic()
    {
        if (isInRange == false && DialogueFinished == true)
        {
            backgroundMusicScriptRef.audioSource.volume = 0;

            while (backgroundMusicScriptRef.audioSource.volume < 1)
            {
                backgroundMusicScriptRef.audioSource.volume += Time.fixedDeltaTime / backgroundMusicScriptRef.dearceseOrIncreaseVolume;
                yield return null;
            }
        }

        backgroundMusicScriptRef.audioSource.volume = 1;
    }

    #endregion
}

What could be the issue here? I am starting the FadeInMusicCoroutine again in OnTriggerExit2D, but it doesn’t seem to work after the first interaction.

I’m looking forward to any help or suggestions!

FadeInMusicCoroutine does not become null when the coroutine finishes, it still keeps referencing the finished coroutine. Therefore the FadeInMusicCoroutine == null check only returns true the first time and then never again. You need to either create a bool field to check for whether the coroutine is running or else set FadeInMusicCoroutine to null at the end of the coroutine.

1 Like