/** This is where the bulk of the dialogue system is.
     * It will get the appropriate dialogue to display and run the typewriter effect.
     */
    private void GetNextDialogue()
    {
        if (finishedTyping)
        {
            currentDialogue = GetCurrentDialogue();

            // Check if there are any other dialogue to display.
            // If not, we close the dialogue.
            if (currentDialogueIndex < currentDialogue.dialogue.Count)
            {
                finishedTyping = false;

                textMeshAnimator.text = currentDialogue.dialogue[currentDialogueIndex];
                textToType            = textMesh.text;
                textMesh.text         = "";

                ShowDialogue();

                StopAllCoroutines(); // Stop previous typewriter.
                StartCoroutine(Typewriter());
            }
            else
            {
                ExitConversation();
            }
        }
    }
    /** Get the name of the button's text and use it to find the ResponseObject.
     * The button's text was set by the ResponseObject's responseText in the ShowResponses() method.
     * Therefore, allowing us to use it to find which responseObject to use.
     */
    public void OnResponseClick()
    {
        currentDialogue = GetCurrentDialogue();

        string     buttonPressed    = EventSystem.current.currentSelectedGameObject.GetComponentInChildren <TextMeshProUGUI>().text;
        D_Response selectedResponse = null;

        // Find response object with same text value.
        foreach (D_Response response in currentDialogue.responseOptions)
        {
            if (response.responseText == buttonPressed)
            {
                selectedResponse = response;
                break;
            }
        }

        // Update dialogue to show response.
        responseDialogue     = selectedResponse.dialogueObject;
        currentDialogueIndex = 0;
        responsePressed      = true;

        HideResponses();
        GetNextDialogue();
    }
    public void InitializeConversation(D_Dialogue dialogue)
    {
        startDialogue   = dialogue;
        currentDialogue = startDialogue;

        initializedConversation = true;
        resetConversation       = false;
    }
    /** Create a typewriter effect by displaying letters one by one.
     */
    private IEnumerator Typewriter()
    {
        for (int i = 0; i < textToType.Length; i++)
        {
            // Check for rich text. Skip them so typewriter effect doesn't apply.
            if (textToType[i] == '<')
            {
                string richtext = "";
                for (int j = i; j < textToType.Length; j++)
                {
                    richtext += textToType[j];
                    if (textToType[j] == '>')
                    {
                        // Hotfix for index out of bounds when we do i = j+1
                        if (j + 1 >= textToType.Length)
                        {
                            textToType += " ";
                        }

                        i              = j + 1;
                        textMesh.text += richtext;
                        break;
                    }
                }
            }

            textMesh.text += textToType[i];
            textMeshAnimator.SyncToTextMesh();

            yield return(new WaitForSeconds(1 / currentDialogue.typingSpeed));
        }

        finishedTyping = true;
        currentDialogueIndex++;

        if (currentDialogueIndex - 1 == currentDialogue.dialogue.Count - 1)
        {
            if (currentDialogue.nextDialogue != null)
            {
                currentDialogue      = currentDialogue.nextDialogue;
                currentDialogueIndex = 0;
            }
            else
            {
                // Show responses at the end of dialogues & when typewriter finished.
                ShowResponses();
            }
        }
    }
    /** Enable as many buttons as there are responses.
     */
    private void ShowResponses()
    {
        currentDialogue = GetCurrentDialogue();

        if (currentDialogue.responseOptions.Count > 0)
        {
            int children = responsesGameObject.transform.childCount;

            GameObject currentButton;

            for (int i = 0; i < children && i < currentDialogue.responseOptions.Count; i++)
            {
                currentButton = responsesGameObject.transform.GetChild(i).gameObject;
                currentButton.SetActive(true);
                currentButton.GetComponent <Button>().onClick.AddListener(OnResponseClick);
                currentButton.GetComponentInChildren <TextMeshProUGUI>().text = currentDialogue.responseOptions[i].responseText;
            }
        }
    }