Nested coroutine can't detected key input?

I made a coroutine which I wanted to stop when any key was pressed and that worked perfectly. Then I decided to fancy it up, which involved adding a nested coroutine, and no matter how I arranged it, that nested coroutine could not detect any key presses.

I ended up having to make use of a bool in Update for the coroutine to check for which works fine, I’m just curious if keys are supposed to be detected by nested coroutines, as I could not find it explicitly stated anywhere that they are not.

Here is the code that wouldn’t work. The debugs for key press in the nested coroutine never triggered:

    IEnumerator DisplayDialogue()
    {
        isDisplayingText = true;

        // Iterate through the dialogue texts
        for (int i = 0; i < currentDialogueNode.dialogueTexts.Count; i++)
        {
            // Clear the dialogue text
            dialogueText.text = "";            

            // Set the dialogue text to the current text in the list
            // dialogueText.text = currentDialogueNode.dialogueTexts[i].myString;           

            // Display dialogue text with typewriter effect
            yield return StartCoroutine(TypeText(currentDialogueNode.dialogueTexts[i].myString));


            // Wait for a key press or any other input mechanism you prefer
            yield return new WaitForSeconds(0.2f); 
            yield return new WaitUntil(() => Input.anyKeyDown);           
        }

        // All texts are displayed; wait for any key press to close the dialogue box
        yield return new WaitUntil(() => Input.anyKeyDown);

        // Hide the dialogue box
        ToggleDialogueBox(false);

        isDisplayingText = false;        

    }

// Coroutine for typing out text one letter at a time
IEnumerator TypeText(string text)
{
    foreach (char letter in text)
    {
        dialogueText.text += letter;

        // Check for any key press to complete the text
// this did not work even outside of the foreach loop or anywhere. i got so desperate i added a check for mouse input on top of anykeydown which i am pretty sure already does that!
        if (Input.anyKeyDown || Input.GetMouseButtonDown(0))
        {
            Debug.Log("Key detected.");
            dialogueText.text = text;
            yield break;
        }

        // Wait for a short delay before the next letter
        yield return new WaitForSeconds(letterDelay);
    }
}

Hi, happy to see you found an alternative to make it work :muscle:

I have the impression that the line below might be playing tricks on your code:

// Wait for a short delay before the next letter
yield return new WaitForSeconds(letterDelay);

During the nested coroutine TypeText , you print the dialog text char by char, waiting a small delay between characters. However, Input.anyKeyDown returns true only during the first frame after the action is performed, so unless you are perfectly precise with your key to match the first frame after letterDelay, it will return false.

You can check that the input is properly captured from nested coroutines with an easy sample:

IEnumerator TypeText(string text)
{
    foreach (var letter in text)
    {
        dialogueText.text += letter;

        yield return new WaitUntil(() =>
        {
            if (Input.anyKeyDown)
            {
                return true;
            }

            return false;
        });

        yield return new WaitForSeconds(0.2f); 
    }
}

This version of your method (only for demonstration purpose) waits for an input before printing each char. I have expanded the WaitUntil so you can set a breakpoint easily in the return true; line.

I hope that helps!