Pausing and Resuming Coroutine

Hi there im working on a pause menu and i got it basically working but the thing is the menu isnt actually pausing the coroutine is still typing out the dialogue and based on how its setup when the player returns to the game it returns to the beginning of the scene, which i did for now so it at least has some way to return. So what i did is an if statement with a bool that when the bool pauser is true(the pause menu has been opened) the coroutine should be paused but that didnt work. So i did a test to verify its going through the if statement and it is so im not sure why its not pausing. Any ideas?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DialogueSystem : MonoBehaviour
{
    public static DialogueSystem instance;
    public ELEMENTS elements;
    public GameObject speakerNameBox;

    public Animator animator;

    public GameObject CTC;

    public bool pauser = false;

    DialogueScript pausechecker;
   
    private void Awake()
    {
        instance = this;
       
       
    }
    // Start is called before the first frame update
    void Start()
    {
        pauser = false;
              
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            pauser = true;

        }
       
    }


    public void Say(string speech, string speaker = "")
    {
        StopSpeaking();
       

        speaking = StartCoroutine(Speaking(speech, false, speaker));
        CTC.SetActive(false);
        animator.SetBool("isResize", false);

    }

    public void SayAdd(string speech, string speaker = "")
    {
        StopSpeaking();
        speechText.text = targetSpeech;

        speaking = StartCoroutine(Speaking(speech, true, speaker));
    }
    public void StopSpeaking()
    {
        if(isSpeaking)
        {
            StopCoroutine(speaking);
        }
        speaking = null;
    }

    public bool isSpeaking { get { return speaking != null; } }
    [HideInInspector] public bool isWaitingForUserInput = false;

    string targetSpeech = "";
    Coroutine speaking = null;

    IEnumerator Speaking(string speech, bool additive, string speaker = "")
    {
       

        speechPanel.SetActive(true);

        targetSpeech = speech;
        if (!additive)
            speechText.text = "";
        else
            targetSpeech = speechText.text + targetSpeech;
       
        speakerNameText.text = speaker;
        isWaitingForUserInput = false;

        if (speaker == "")
            speakerNameBox.SetActive(false);
        else
            speakerNameBox.SetActive(true);

        while(speechText.text != targetSpeech)
        {
           

          
            speechText.text += targetSpeech[speechText.text.Length];

            if (pauser == true)
            {
                yield return null;
            }
            else if(pauser == false)
                yield return new WaitForEndOfFrame();

        }

       

        isWaitingForUserInput = true;

        while (isWaitingForUserInput)
        {
            if (pauser == true)
            {
                yield return null;
            }
            else if(pauser == false)
            {

                CTC.SetActive(true);
                animator.SetBool("isResize", true);

                yield return new WaitForEndOfFrame();

            }

        }
          
        StopSpeaking();

    }

    [System.Serializable]
    public class ELEMENTS
    {
        public GameObject speechPanel;
        public TextMeshProUGUI speakerNameText;
        public TextMeshProUGUI speechText;

    }
    public GameObject speechPanel { get { return elements.speechPanel; } }
    public TextMeshProUGUI speakerNameText { get { return elements.speakerNameText; } }
    public TextMeshProUGUI speechText { get { return elements.speechText; } }
}

yield return null is pretty much identical to yield return new WaitForEndOfFrame().

You should basically only modify your dialogue state (adding typed letters, etc.) if your pause status is false.

Separately, you have a habit of using “else if” unnecessarily. The second snip below is more natural:

if (condition == true)
    ...
else if (condition == false)
    ...
if (condition)
    ...
else
    ...

so basically something like this?

while(speechText.text != targetSpeech)
        {
 

            if (pauser == true)
            {
                yield return null;
            }
            else
                speechText.text += targetSpeech[speechText.text.Length];
                yield return new WaitForEndOfFrame();

        }

You need to put curly braces around your else block, or only the first line will happen after the else.

However, since both the if and the else are both yielding for a frame, you can change your logic to something more concise:

while(speechText.text != targetSpeech)
{
    if(!paused)
    {
        speechText.text += targetSpeed[speechText.text.Length];
    }

    yield return null;
}