Does anybody know why my dialogue is not appearing when I play it in Unity for my visual novel?

For context, I’m creating a visual novel following this tutorial. (I was stuck at 6:22) Prior to this part of the tutorial, everything was working fine. The things I changed here is I replaced it with my own characters.

Please be patient with me since I think there will be a lot of scripts that I have to include here. Let me know if I’m miss something out. Thank you! :sob:

Here’s a testing script I did:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CHARACTERS;
using DIALOGUE;

namespace TESTING
{
    public class TestCharacters : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {
            
            // Character Narrator = CharacterManager.instance.CreateCharacter("Narrator");
            // Character Effects = CharacterManager.instance.CreateCharacter("Effects");

            StartCoroutine(Test());
        }

        IEnumerator Test()
        {
            Character Williams = CharacterManager.instance.CreateCharacter("Mr. Williams");

            List<string> lines = new List<string>()
            {
                "Hi, there!",
                "My name is Williams.",
                "What's your name?",
                "Oh, {wa 1} that's very nice."
            };

            yield return Williams.Say(lines);

            Debug.Log("Finished");
        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}

Here’s my Dialogue System:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

namespace DIALOGUE
{
    public class DialogueSystem : MonoBehaviour
    {
        [SerializeField] private DialogueSystemConfigurationSO _config;
        public DialogueSystemConfigurationSO config => _config;

        public DialogueContainer dialogueContainer = new DialogueContainer();
        private ConversationManager conversationManager;
        private TextArchitect architect;

        public static DialogueSystem instance { get; private set; }

        public delegate void DialogueSystemEvent();
        public event DialogueSystemEvent onUserPrompt_Next;

        public bool isRunningConversation => conversationManager.isRunning;

        private void Awake()
        {
            if (instance == null)
            {
                instance = this;
                Initialize();
            }
            else
                DestroyImmediate(gameObject);
        }

        bool _initialized = false;

        private void Initialize()
        {
            if (_initialized)
                return;
            
            architect = new TextArchitect(dialogueContainer.dialogueText);
            conversationManager = new ConversationManager(architect);
        }

        public void OnUserPrompt_Next()
        {
            onUserPrompt_Next?.Invoke();
        }

        public void ShowSpeakerName(string speakerName = "") 
        {
            if (speakerName.ToLower() != "narrator")
            dialogueContainer.nameContainer.Show(speakerName);
            else
                HideSpeakerName();
        }

        public void HideSpeakerName() => dialogueContainer.nameContainer.Hide();

        public Coroutine Say(string speaker, string dialogue)
        {
            List<string> conversation = new List<string>() { $"{speaker} \"{dialogue}\"" };
            return Say(conversation);
        }

        public Coroutine Say(List<string> conversation)
        {
            return conversationManager.StartConversation(conversation);
        }
    }
}

Here’s my Character script:

using DIALOGUE;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace CHARACTERS    // BASE CLASS FROM WHICH ALL CHARACTER TYPES DERIVE FROM

{
    public abstract class Character  
    {
        public string name = "";
        public RectTransform root = null;

        public Character(string name)
        {
            this.name = name;
        }

        public Coroutine Say(string dialogue) => Say(new List<string> { dialogue} );

        public Coroutine Say(List<string> dialogue)
        {

            return DialogueSystem.instance.Say(dialogue);
        }

        public enum CharacterType
        {
            Text,
            Sprite,
            SpriteSheet
        }

    }
}

And here’s my conversation manager script:

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using COMMANDS;

namespace DIALOGUE
{
    public class ConversationManager
    {
        private DialogueSystem dialogueSystem => DialogueSystem.instance;

        private Coroutine process = null;

        public bool isRunning => process != null;

        private TextArchitect architect = null;
        private bool userPrompt = false;

        public ConversationManager(TextArchitect architect)
        {
            this.architect = architect;
            dialogueSystem.onUserPrompt_Next += OnUserPrompt_Next;
        }

        private void OnUserPrompt_Next()
        {
            userPrompt = true;
        }

        public Coroutine StartConversation(List<string> conversation)
        {
            StopConversation();

            process = dialogueSystem.StartCoroutine(RunningConversation(conversation));

            return process;

        }

        public void StopConversation()
        {
            if (!isRunning)
                return;

            dialogueSystem.StopCoroutine(process);
            process = null;
        }

        IEnumerator RunningConversation(List<string> conversation)
        {
            for (int i = 0; i < conversation.Count; i++)
            {
                //Dont show any blank lines or try to run any logic on them
                if (string.IsNullOrWhiteSpace(conversation[i]))
                    continue;

                DIALOGUE_LINE line = DialogueParser.Parse(conversation[i]);

                //show dialogue
                if (line.hasDialogue)
                    yield return Line_RunDialogue(line);

                //Run any commands
                if (line.hasCommands)
                    yield return Line_RunCommands(line);

                if (line.hasDialogue)
                    //Wait for User Input
                    yield return WaitForUserInput();

            }
        }

        IEnumerator Line_RunDialogue(DIALOGUE_LINE line)
        {
            //Show or hide the speaker name if there is one present.
            if (line.hasSpeaker)
                dialogueSystem.ShowSpeakerName(line.speakerData.displayname);

            //Build dialogue
            yield return BuildLineSegments(line.dialogueData);
        }


        IEnumerator Line_RunCommands(DIALOGUE_LINE line)
        {
            List<DL_COMMAND_DATA.Command> commands = line.commandData.commands;

            foreach(DL_COMMAND_DATA.Command command in commands)
            {
                if (command.waitForCompletion)
                    yield return CommandManager.instance.Execute(command.name, command.arguments);
                else
                    CommandManager.instance.Execute(command.name, command.arguments);
            }
            
            yield return null;
        }

        

        IEnumerator BuildLineSegments(DL_DIALOGUE_DATA line)
        {
           for(int i = 0; i < line.segments.Count; i++) 
           {
                DL_DIALOGUE_DATA.DIALOGUE_SEGMENT segment = line.segments[i];

                yield return WaitForDialogueSegmentSignalToBeTriggered(segment);

                yield return BuildDialogue(segment.dialogue, segment.appendText);
           }
        }

        IEnumerator WaitForDialogueSegmentSignalToBeTriggered(DL_DIALOGUE_DATA.DIALOGUE_SEGMENT segment)
        {
            switch(segment.startSignal)
            {
                case DL_DIALOGUE_DATA.DIALOGUE_SEGMENT.StartSignal.C:
                case DL_DIALOGUE_DATA.DIALOGUE_SEGMENT.StartSignal.A:
                    yield return WaitForUserInput();
                    break;
                case DL_DIALOGUE_DATA.DIALOGUE_SEGMENT.StartSignal.WC:
                case DL_DIALOGUE_DATA.DIALOGUE_SEGMENT.StartSignal.WA:
                    yield return new WaitForSeconds(segment.signalDelay);
                    break;
                default:
                    break;

            }
        }


        IEnumerator BuildDialogue(string dialogue, bool append = false)
        {
            if (!append)
                architect.Build(dialogue);
            else   
                architect.Append(dialogue);

            while (architect.isBuilding)        gawing hindi Hurryup pag sakin. Check kung pwede force complete lang p
            {
                if (userPrompt)
                {
                    if (!architect.hurryUp)
                        architect.hurryUp = true;
                    else
                        architect.ForceComplete();  /

                    userPrompt = false;
                }
                yield return null;
            }
        }

        IEnumerator WaitForUserInput()
        {
            while(!userPrompt)
                yield return null;

            userPrompt = false;
        }
       
    }
}

You need to add some Debug.Logs to find out when it is starting to fail. It’s a little complicated to just eyeball it. Are lines being correctly passed into the dialogue system? Are those being processed as expected? etc

I’m also not seeing a point where you gameObject.SetActive(true) any UI elements, though perhaps that doesn’t matter if it is in fact failing earlier than that.

1 Like

Thank you! Will look into Debug.Logs. I guess I’m in the part where it gets complicated (for me :sweat_smile: :smiling_face_with_tear:) I already have a feeling about it because it’s dealing with a lot of script now. Anyway, thanks again!