Why is an else-if statement breaking my dialogue system?

A dialogue system I created uses a method called ReadLine() to type out the speaker’s text like a typewriter. This method takes a string for the speaker’s name, a string for the speaker’s text, and an integer index to keep track of the conversation every time a key is pushed. However, when the speaker’s name is null, the text does not get typed out when it is called for the first time. The problem seems to stem from the else-if statement within ReadLine(), but I am unable to figure out why as it has nothing to do with the speaker’s name. Any help would be appreciated.

Dialogue Script:

public class DialogueScript : MonoBehaviour
{
    private Image dialogueBox;
    private TextMeshProUGUI nameBox;
    private TextMeshProUGUI textBox;
    private float textSpeed = 0.05f;
    private int textIndex;

    //Reference to dialogue box:
    void Start()
    {
        dialogueBox = GameObject.Find("Overlay").transform.GetChild(5).GetComponent<Image>();
        nameBox = dialogueBox.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
        textBox = dialogueBox.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
    }

    //Play dialogue:
    void Update()
    {
        OpenDialogueBox();
        ReadLine("Johnny", "I have a question!", 1);
        ReadLine(null, "Answer the question?", 2);
        ReadLine(null, "Are you sure?", 3);
        ReadLine("Roderick", "Ask away.", 4);
        CloseDialogueBox(5);
    }

    //Open dialogue box:
    void OpenDialogueBox()
    {
        if (!dialogueBox.gameObject.activeSelf && Input.GetKeyDown(KeyCode.T))
        {
            dialogueBox.gameObject.SetActive(true);
            nameBox.text = string.Empty;
            textBox.text = string.Empty;
            textIndex = 1;
        }
    }

    //Close dialogue box:
    void CloseDialogueBox(int closingIndex)
    {
        if (closingIndex == textIndex)
        {
            StopAllCoroutines();
            dialogueBox.gameObject.SetActive(false);
        }
    }

    //Types script to dialogue box:
    void ReadLine(string name, string text, int num)
    {
        text = "\"" + text + "\"";

        if (Input.GetKeyDown(KeyCode.T) && num == textIndex)
        {
            nameBox.text = name;

            if (textBox.text == text)
            {
                textIndex++;
            }
            else if (textBox.text.Length < text.Length && textBox.text.Length > 0)
            {
                StopAllCoroutines();
                textBox.text = text;
            }
            else
            {
                textBox.text = string.Empty;
                StartCoroutine(TypeLine(name, text));
            }
        }
    }

    //Typewriter effect:
    IEnumerator TypeLine(string name, string text)
    {
        foreach (char letter in text)
        {
            textBox.text += letter;
            yield return new WaitForSeconds(textSpeed);
        }
    }
}

This is only true at the frame when the key is first pressed. Not any time after that.

Input.GetKeyDown(KeyCode.T)

The rest is also broken

//if typewriter effect finished
if (textBox.text == text)
{
    textIndex++; //next text
    //but this will never happen because Input.GetKeyDown(KeyCode.T) is not true here
}
//if typewriter effect not finished and not at char 0
else if (textBox.text.Length < text.Length && textBox.text.Length > 0)
{
    StopAllCoroutines(); //so you stop the typewriter effect directly at char 1 which is wrong
    textBox.text = text; //typewriter effect set to finished
    //but this will never happen because Input.GetKeyDown(KeyCode.T) is not true here
}
//else (only happens at char 0)
else
{
    //so this is the only thing that runs
    textBox.text = string.Empty;
    StartCoroutine(TypeLine(name, text)); //start typewriter effect
    // and because you have no check for if the coroutine already runs you
    // start a coroutine again on each T-key press, but only if it is pressed
    // before the coroutine has set the first char of textBox.text.
    //you see here that the way you are doing it is not right, you must have
    // a state (isStarted, isDone)...
}

You are also both setting textBox.text and checking textBox.text in the else-if block which makes it hard to understand what is happening.

I still think my last answer is correct and clean, but you have to add a keypress check for it to work like you want.

//New state variables
bool effectStarted = false;
bool effectDone = false;

//Types script to dialogue box:
void ReadLine(string name, string text, int num)
{
    if (num == textIndex)
    {
        text = "\"" + text + "\"";
        if (!effectStarted &&
            Input.GetKeyDown(KeyCode.T)) //this is new, check for keypress when effect not started
        {
            nameBox.text = name;
            effectStarted = true;
            effectDone = false;
            StartCoroutine(TypeLine(name, text));
        }
        else if(Input.GetKeyDown(KeyCode.T)) //update: this is new
        {
            textBox.text = text;
            StopAllCoroutines();
            effectDone = true;
        }
        if (effectDone)
        {
            textIndex++;
            effectStarted = false;
        }
    }
}

//Typewriter effect:
IEnumerator TypeLine(string name, string text)
{
    foreach (char letter in text)
    {
        textBox.text += letter;
        yield return new WaitForSeconds(textSpeed);
    }
    effectDone = true;
}

@rh_galaxy

Your code is working now. In the last thread, it didn’t work because the input that prevented the text from playing continuously was removed, which confused me. However, the else-if statement was used to fill in the text box if the player did not want to wait for the typewriter. Since I shouldn’t be stopping any coroutines while dialogue plays, how am I supposed to print out the text without causing TypeLine() to continue to type? If that is not possible, I will accept a way to speed up the typewriter while the same key input is held down.