private SpeechNode CreateSpeechNode(EditableSpeechNode editableNode)
        {
            SpeechNode speech = new SpeechNode();

            speech.Name = editableNode.Name;
            speech.Text = editableNode.Text;
            speech.AutomaticallyAdvance           = editableNode.AdvanceDialogueAutomatically;
            speech.AutoAdvanceShouldDisplayOption = editableNode.AutoAdvanceShouldDisplayOption;
            speech.TimeUntilAdvance = editableNode.TimeUntilAdvance;
            speech.TMPFont          = editableNode.TMPFont;
            speech.Icon             = editableNode.Icon;
            speech.Audio            = editableNode.Audio;
            speech.Volume           = editableNode.Volume;

            CopyParamActions(editableNode, speech);

            NodeEventHolder holder = this.GetNodeData(editableNode.ID);

            if (holder != null)
            {
                speech.Event = holder.Event;
            }

            return(speech);
        }
        //--------------------------------------
        // Construct User-Facing Conversation Object and Nodes
        //--------------------------------------

        private Conversation ConstructConversationObject(EditableConversation ec)
        {
            // Create a conversation object
            Conversation conversation = new Conversation();

            // Construct the parameters
            CreateParameters(ec, conversation);

            // Create a dictionary to store our created nodes by UID
            Dictionary <int, SpeechNode> speechByID  = new Dictionary <int, SpeechNode>();
            Dictionary <int, OptionNode> optionsByID = new Dictionary <int, OptionNode>();

            // Create a Dialogue and Option node for each in the conversation
            // Put them in the dictionary
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                SpeechNode node = CreateSpeechNode(ec.SpeechNodes[i]);
                speechByID.Add(ec.SpeechNodes[i].ID, node);
            }

            for (int i = 0; i < ec.Options.Count; i++)
            {
                OptionNode node = CreateOptionNode(ec.Options[i]);
                optionsByID.Add(ec.Options[i].ID, node);
            }

            // Now that we have every node in the dictionary, reconstruct the tree
            // And also look for the root
            ReconstructTree(ec, conversation, speechByID, optionsByID);

            return(conversation);
        }
Exemple #3
0
        private void CreateUIOptions()
        {
            // Display new options
            if (m_currentSpeech.ConnectionType == Connection.eConnectionType.Option)
            {
                for (int i = 0; i < m_currentSpeech.Connections.Count; i++)
                {
                    OptionConnection connection = m_currentSpeech.Connections[i] as OptionConnection;
                    if (ConditionsMet(connection))
                    {
                        UIConversationButton uiOption = CreateButton();
                        uiOption.SetupButton(UIConversationButton.eButtonType.Option, connection.OptionNode);
                    }
                }
            }
            // Display Continue/End options
            else
            {
                bool notAutoAdvance             = !m_currentSpeech.AutomaticallyAdvance;
                bool allowVisibleOptionWithAuto = (m_currentSpeech.AutomaticallyAdvance && m_currentSpeech.AutoAdvanceShouldDisplayOption);

                if (notAutoAdvance || allowVisibleOptionWithAuto)
                {
                    if (m_currentSpeech.ConnectionType == Connection.eConnectionType.Speech)
                    {
                        UIConversationButton uiOption = CreateButton();
                        SpeechNode           next     = GetValidSpeechOfNode(m_currentSpeech);

                        // If there was no valid speech node (due to no conditions being met) this becomes a None button type
                        if (next == null)
                        {
                            uiOption.SetupButton(UIConversationButton.eButtonType.End, null, endFont: m_conversation.EndConversationFont);
                        }
                        // Else, valid speech node found
                        else
                        {
                            uiOption.SetupButton(UIConversationButton.eButtonType.Speech, next, continueFont: m_conversation.ContinueFont);
                        }
                    }
                    else if (m_currentSpeech.ConnectionType == Connection.eConnectionType.None)
                    {
                        UIConversationButton uiOption = CreateButton();
                        uiOption.SetupButton(UIConversationButton.eButtonType.End, null, endFont: m_conversation.EndConversationFont);
                    }
                }
            }
            SetSelectedOption(0);

            // Set the button sprite and alpha
            for (int i = 0; i < m_uiOptions.Count; i++)
            {
                m_uiOptions[i].SetImage(OptionImage, OptionImageSliced);
                m_uiOptions[i].SetAlpha(0);
                m_uiOptions[i].gameObject.SetActive(false);
            }
        }
Exemple #4
0
        //--------------------------------------
        // Public functions
        //--------------------------------------

        public void StartConversation(NPCConversation conversation)
        {
            m_conversation = conversation.Deserialize();
            if (OnConversationStarted != null)
            {
                OnConversationStarted.Invoke();
            }

            TurnOnUI();
            m_currentSpeech = m_conversation.Root;
            SetState(eState.TransitioningDialogueBoxOn);
        }
Exemple #5
0
        public void StartConversationWithoutDeserialization(NPCConversation conversation)
        {
            m_conversation = conversation.RuntimeLoad();
            if (OnConversationStarted != null)
            {
                OnConversationStarted.Invoke();
            }

            TurnOnUI();
            ClearOptions();
            m_pendingDialogue = m_conversation.Root;
            SetState(eState.TransitioningDialogueBoxOn);
        }
Exemple #6
0
        //--------------------------------------
        // Util
        //--------------------------------------

        private bool IsAutoAdvance()
        {
            if (m_currentSpeech.ConnectionType == Connection.eConnectionType.Speech)
            {
                SpeechNode next = GetValidSpeechOfNode(m_currentSpeech);
                if (next != null)
                {
                    SetupSpeech(next);
                    return(true);
                }
            }
            else if (m_currentSpeech.ConnectionType == Connection.eConnectionType.None)
            {
                EndConversation();
                return(true);
            }
            return(false);
        }
Exemple #7
0
        private void TransitionOptionsOff_Update()
        {
            m_stateTime += Time.deltaTime;
            float t = m_stateTime / TRANSITION_TIME;

            if (t > 1)
            {
                ClearOptions();

                if (m_currentSpeech.AutomaticallyAdvance)
                {
                    if (IsAutoAdvance())
                    {
                        return;
                    }
                }

                if (m_selectedOption == null)
                {
                    EndConversation();
                    return;
                }

                SpeechNode nextSpeech = GetValidSpeechOfNode(m_selectedOption);
                if (nextSpeech == null)
                {
                    EndConversation();
                }
                else
                {
                    SetupSpeech(nextSpeech);
                }
                return;
            }


            for (int i = 0; i < m_uiOptions.Count; i++)
            {
                m_uiOptions[i].SetAlpha(1 - t);
            }

            SetColorAlpha(DialogueText, 1 - t);
        }
        private void ReconstructTree(EditableConversation ec, Conversation conversation, Dictionary <int, SpeechNode> dialogues, Dictionary <int, OptionNode> options)
        {
            // Speech nodes
            List <EditableSpeechNode> editableSpeechNodes = ec.SpeechNodes;

            for (int i = 0; i < editableSpeechNodes.Count; i++)
            {
                EditableSpeechNode editableNode = editableSpeechNodes[i];
                SpeechNode         speechNode   = dialogues[editableNode.ID];

                // Connections
                List <EditableConnection> editableConnections = editableNode.Connections;
                for (int j = 0; j < editableConnections.Count; j++)
                {
                    int childID = editableConnections[j].NodeUID;

                    // Construct node->Speech
                    if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech)
                    {
                        SpeechConnection connection = new SpeechConnection(dialogues[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        speechNode.Connections.Add(connection);
                    }
                    // Construct node->Option
                    else if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Option)
                    {
                        OptionConnection connection = new OptionConnection(options[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        speechNode.Connections.Add(connection);
                    }
                }

                // Root?
                if (editableNode.EditorInfo.isRoot)
                {
                    conversation.Root = dialogues[editableNode.ID];
                }
            }


            // Option nodes
            List <EditableOptionNode> editableOptionNodes = ec.Options;

            for (int i = 0; i < editableOptionNodes.Count; i++)
            {
                EditableOptionNode editableNode = editableOptionNodes[i];
                OptionNode         optionNode   = options[editableNode.ID];

                // Connections
                List <EditableConnection> editableConnections = editableNode.Connections;
                for (int j = 0; j < editableConnections.Count; j++)
                {
                    int childID = editableConnections[j].NodeUID;

                    // Construct node->Speech
                    if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech)
                    {
                        SpeechConnection connection = new SpeechConnection(dialogues[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        optionNode.Connections.Add(connection);
                    }
                }
            }
        }
Exemple #9
0
 public SpeechConnection(SpeechNode node)
 {
     SpeechNode = node;
 }
Exemple #10
0
        //--------------------------------------
        // Do Speech
        //--------------------------------------

        public void DoSpeech(SpeechNode speech)
        {
            if (speech == null)
            {
                EndConversation();
                return;
            }

            m_currentSpeech = speech;

            // Clear current options
            ClearOptions();
            m_currentSelectedIndex = -1;

            // Set sprite
            if (speech.Icon == null)
            {
                NpcIcon.sprite = BlankSprite;
            }
            else
            {
                NpcIcon.sprite = speech.Icon;
            }

            // Set font
            if (speech.TMPFont != null)
            {
                DialogueText.font = speech.TMPFont;
            }
            else
            {
                DialogueText.font = null;
            }

            // Set name
            NameText.text = speech.Name;

            // Set text
            if (string.IsNullOrEmpty(speech.Text))
            {
                if (ScrollText)
                {
                    DialogueText.text                 = "";
                    m_targetScrollTextCount           = 0;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = "";
                    DialogueText.maxVisibleCharacters = 1;
                }
            }
            else
            {
                if (ScrollText)
                {
                    DialogueText.text                 = speech.Text;
                    m_targetScrollTextCount           = speech.Text.Length + 1;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = speech.Text;
                    DialogueText.maxVisibleCharacters = speech.Text.Length;
                }
                //if (Backlog != null)
                //{
                //    Backlog.text += speech.Name + ":\n" + speech.Text + "\n\n";
                //}
            }


            // Call the event
            //speech.Event?.Invoke();

            // Play the audio
            if (speech.Audio != null)
            {
                AudioPlayer.clip   = speech.Audio;
                AudioPlayer.volume = speech.Volume;
                AudioPlayer.Play();
            }

            // Display new options
            if (speech.Options.Count > 0)
            {
                //StartCoroutine(ShrinkDialogue());

                // Decrease spacing when many options are present to prevent options being too small
                var layout = OptionsPanel.GetComponent <VerticalLayoutGroup>();
                if (speech.Options.Count > 3)
                {
                    layout.spacing = 10;
                }
                else
                {
                    layout.spacing = 20;
                }

                for (int i = 0; i < speech.Options.Count; i++)
                {
                    UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                    option.InitButton(speech.Options[i]);
                    option.SetOption(speech.Options[i]);
                    m_uiOptions.Add(option);
                }
            }
            else
            {
                //StartCoroutine(ExpandDialogue());
                // Display "Continue" / "End" if we should.
                //bool notAutoAdvance = !speech.AutomaticallyAdvance;
                bool autoWithOption = (speech.AutomaticallyAdvance && speech.AutoAdvanceShouldDisplayOption);
                if (autoWithOption)
                {
                    // Else display "continue" button to go to following dialogue
                    if (speech.Dialogue != null)
                    {
                        UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                        option.SetFollowingAction(speech.Dialogue);
                        m_uiOptions.Add(option);
                    }
                    // Else display "end" button
                    else
                    {
                        UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                        option.SetAsEndConversation();
                        m_uiOptions.Add(option);
                    }
                }
            }
            // Auto select first option
            // SetSelectedOption(0);

            // Set the button sprite and alpha
            for (int i = 0; i < m_uiOptions.Count; i++)
            {
                m_uiOptions[i].SetImage(OptionImage, OptionImageSliced);
                m_uiOptions[i].SetAlpha(0);
                m_uiOptions[i].gameObject.SetActive(false);
            }

            SetState(eState.ScrollingText);
        }
Exemple #11
0
 public void TurnOffPortraitAndPauseConversation()
 {
     m_pendingDialogue = m_currentSpeech.Dialogue;
     NpcIcon.gameObject.SetActive(false);
     SetState(eState.freeze);
 }
Exemple #12
0
        //--------------------------------------
        // (CUSTOM) Pause/Continue Conversation
        //--------------------------------------

        public void PauseConversation()
        {
            m_pendingDialogue = m_currentSpeech.Dialogue;
            SetState(eState.TransitioningDialogueOff);
        }
Exemple #13
0
        //--------------------------------------
        // Update
        //--------------------------------------

        private void Update()
        {
            // Use method to compute if we should progress or not
            bool progressInput = Progress();

            if (m_state != eState.Off)
            {
                if (Input.GetKeyDown(KeyCode.LeftControl))
                {
                    skipping = !skipping;
                }
            }

            //if (Input.mouseScrollDelta.y > 0.2f && !BacklogGameObject.activeSelf) {
            //    ToggleBacklog();
            //} else if (Input.mouseScrollDelta.y < -0.2f && BacklogGameObject.activeSelf) {
            //    ToggleBacklog();
            //}

            switch (m_state)
            {
            case eState.TransitioningDialogueBoxOn:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    DoSpeech(m_pendingDialogue);
                    return;
                }

                SetColorAlpha(DialogueBackground, t);
                SetColorAlpha(NpcIcon, t);
                SetColorAlpha(NameText, t);
            }
            break;

            case eState.ScrollingText:
                UpdateScrollingText();
                break;

            case eState.TransitioningOptionsOn:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    SetState(eState.Idle);

                    return;
                }

                for (int i = 0; i < m_uiOptions.Count; i++)
                {
                    m_uiOptions[i].SetAlpha(t);
                }
            }
            break;

            case eState.Idle:
            {
                m_stateTime += Time.deltaTime;
                if (m_currentSpeech.Dialogue != null || m_currentSpeech.Options == null || m_currentSpeech.Options.Count == 0)
                {
                    if (m_stateTime > m_currentSpeech.TimeUntilAdvance)
                    {
                        if ((progressInput || skipping || m_currentSpeech.AutomaticallyAdvance) && !isFrozen)
                        {
                            SetState(eState.TransitioningOptionsOff);
                        }
                    }
                }
            }
            break;

            case eState.TransitioningOptionsOff:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    ClearOptions();
                    m_currentSpeech.Event?.Invoke();

                    //if (m_currentSpeech.AutomaticallyAdvance)
                    //{
                    if (m_currentSpeech.Dialogue != null)
                    {
                        DoSpeech(m_currentSpeech.Dialogue);
                        return;
                    }
                    else if (m_currentSpeech.Options == null || m_currentSpeech.Options.Count == 0)
                    {
                        EndConversation();
                        return;
                    }
                    //}

                    if (m_selectedOption == null)
                    {
                        EndConversation();
                        return;
                    }

                    SpeechNode nextAction = m_selectedOption.Dialogue;
                    if (nextAction == null)
                    {
                        EndConversation();
                    }
                    else
                    {
                        DoSpeech(nextAction);
                    }
                    return;
                }


                for (int i = 0; i < m_uiOptions.Count; i++)
                {
                    m_uiOptions[i].SetAlpha(1 - t);
                }

                SetColorAlpha(DialogueText, 1 - t);
            }
            break;

            case eState.TransitioningDialogueOff:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    TurnOffUI();
                    return;
                }

                SetColorAlpha(DialogueBackground, 1 - t);
                SetColorAlpha(NpcIcon, 1 - t);
                SetColorAlpha(NameText, 1 - t);
            }
            break;

            case eState.freeze:
                break;
            }
        }
 public void SetFollowingAction(SpeechNode action)
 {
     m_action      = action;
     TextMesh.text = "Continue.";
 }
Exemple #15
0
        //--------------------------------------
        // Do Speech
        //--------------------------------------

        private void SetupSpeech(SpeechNode speech)
        {
            if (speech == null)
            {
                EndConversation();
                return;
            }

            m_currentSpeech = speech;

            // Clear current options
            ClearOptions();
            m_currentSelectedIndex = 0;

            // Set sprite
            if (speech.Icon == null)
            {
                NpcIcon.sprite = BlankSprite;
            }
            else
            {
                NpcIcon.sprite = speech.Icon;
            }

            // Set font
            if (speech.TMPFont != null)
            {
                DialogueText.font = speech.TMPFont;
            }
            else
            {
                DialogueText.font = null;
            }

            // Set name
            NameText.text = speech.Name;

            // Set text
            if (string.IsNullOrEmpty(speech.Text))
            {
                if (ScrollText)
                {
                    DialogueText.text                 = "";
                    m_targetScrollTextCount           = 0;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = "";
                    DialogueText.maxVisibleCharacters = 1;
                }
            }
            else
            {
                if (ScrollText)
                {
                    DialogueText.text                 = speech.Text;
                    m_targetScrollTextCount           = speech.Text.Length + 1;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = speech.Text;
                    DialogueText.maxVisibleCharacters = speech.Text.Length;
                }
            }

            // Call the event
            if (speech.Event != null)
            {
                speech.Event.Invoke();
            }

            DoParamAction(speech);

            // Play the audio
            if (speech.Audio != null)
            {
                AudioPlayer.clip   = speech.Audio;
                AudioPlayer.volume = speech.Volume;
                AudioPlayer.Play();
            }

            if (ScrollText)
            {
                SetState(eState.ScrollingText);
            }
            else
            {
                SetState(eState.TransitioningOptionsOn);
            }
        }
Exemple #16
0
        //--------------------------------------
        // Option Selected
        //--------------------------------------

        public void SpeechSelected(SpeechNode speech)
        {
            SetupSpeech(speech);
        }
Exemple #17
0
        //--------------------------------------
        // Update
        //--------------------------------------

        private void Update()
        {
            switch (m_state)
            {
            case eState.TransitioningDialogueBoxOn:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    DoSpeech(m_pendingDialogue);
                    return;
                }

                SetColorAlpha(DialogueBackground, t);
                SetColorAlpha(NpcIcon, t);
                SetColorAlpha(NameText, t);
            }
            break;

            case eState.ScrollingText:
                UpdateScrollingText();
                break;

            case eState.TransitioningOptionsOn:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    SetState(eState.Idle);
                    return;
                }

                for (int i = 0; i < m_uiOptions.Count; i++)
                {
                    m_uiOptions[i].SetAlpha(t);
                }
            }
            break;

            case eState.Idle:
            {
                m_stateTime += Time.deltaTime;

                if (m_currentSpeech.AutomaticallyAdvance)
                {
                    if (m_currentSpeech.Dialogue != null || m_currentSpeech.Options == null || m_currentSpeech.Options.Count == 0)
                    {
                        if (m_stateTime > m_currentSpeech.TimeUntilAdvance)
                        {
                            SetState(eState.TransitioningOptionsOff);
                        }
                    }
                }
            }
            break;

            case eState.TransitioningOptionsOff:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    ClearOptions();

                    if (m_currentSpeech.AutomaticallyAdvance)
                    {
                        if (m_currentSpeech.Dialogue != null)
                        {
                            DoSpeech(m_currentSpeech.Dialogue);
                            return;
                        }
                        else if (m_currentSpeech.Options == null || m_currentSpeech.Options.Count == 0)
                        {
                            EndConversation();
                            return;
                        }
                    }

                    if (m_selectedOption == null)
                    {
                        EndConversation();
                        return;
                    }

                    SpeechNode nextAction = m_selectedOption.Dialogue;
                    if (nextAction == null)
                    {
                        EndConversation();
                    }
                    else
                    {
                        DoSpeech(nextAction);
                    }
                    return;
                }


                for (int i = 0; i < m_uiOptions.Count; i++)
                {
                    m_uiOptions[i].SetAlpha(1 - t);
                }

                SetColorAlpha(DialogueText, 1 - t);
            }
            break;

            case eState.TransitioningDialogueOff:
            {
                m_stateTime += Time.deltaTime;
                float t = m_stateTime / TRANSITION_TIME;

                if (t > 1)
                {
                    TurnOffUI();
                    return;
                }

                SetColorAlpha(DialogueBackground, 1 - t);
                SetColorAlpha(NpcIcon, 1 - t);
                SetColorAlpha(NameText, 1 - t);
            }
            break;
            }
        }
Exemple #18
0
        //--------------------------------------
        // Do Speech
        //--------------------------------------

        public void DoSpeech(SpeechNode speech)
        {
            if (speech == null)
            {
                EndConversation();
                return;
            }

            m_currentSpeech = speech;

            // Clear current options
            ClearOptions();
            m_currentSelectedIndex = 0;

            // Set sprite
            if (speech.Icon == null)
            {
                NpcIcon.sprite = BlankSprite;
            }
            else
            {
                NpcIcon.sprite = speech.Icon;
            }

            // Set font
            if (speech.TMPFont != null)
            {
                DialogueText.font = speech.TMPFont;
            }
            else
            {
                DialogueText.font = null;
            }

            // Set name
            NameText.text = speech.Name;

            // Set text
            if (string.IsNullOrEmpty(speech.Text))
            {
                if (ScrollText)
                {
                    DialogueText.text                 = "";
                    m_targetScrollTextCount           = 0;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = "";
                    DialogueText.maxVisibleCharacters = 1;
                }
            }
            else
            {
                if (ScrollText)
                {
                    DialogueText.text                 = speech.Text;
                    m_targetScrollTextCount           = speech.Text.Length + 1;
                    DialogueText.maxVisibleCharacters = 0;
                    m_elapsedScrollTime               = 0f;
                    m_scrollIndex = 0;
                }
                else
                {
                    DialogueText.text = speech.Text;
                    DialogueText.maxVisibleCharacters = speech.Text.Length;
                }
            }


            // Call the event
            if (speech.Event != null)
            {
                speech.Event.Invoke();
            }

            // Play the audio
            if (speech.Audio != null)
            {
                AudioPlayer.clip   = speech.Audio;
                AudioPlayer.volume = speech.Volume;
                AudioPlayer.Play();
            }

            // Display new options
            if (speech.Options.Count > 0)
            {
                for (int i = 0; i < speech.Options.Count; i++)
                {
                    UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                    option.InitButton(speech.Options[i]);
                    option.SetOption(speech.Options[i]);
                    m_uiOptions.Add(option);
                }
            }
            else
            {
                // Display "Continue" / "End" if we should.
                bool notAutoAdvance = !speech.AutomaticallyAdvance;
                bool autoWithOption = (speech.AutomaticallyAdvance && speech.AutoAdvanceShouldDisplayOption);
                if (notAutoAdvance || autoWithOption)
                {
                    // Else display "continue" button to go to following dialogue
                    if (speech.Dialogue != null)
                    {
                        UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                        option.SetFollowingAction(speech.Dialogue);
                        m_uiOptions.Add(option);
                    }
                    // Else display "end" button
                    else
                    {
                        UIConversationButton option = GameObject.Instantiate(ButtonPrefab, OptionsPanel);
                        option.SetAsEndConversation();
                        m_uiOptions.Add(option);
                    }
                }
            }
            SetSelectedOption(0);

            // Set the button sprite and alpha
            for (int i = 0; i < m_uiOptions.Count; i++)
            {
                m_uiOptions[i].SetImage(OptionImage, OptionImageSliced);
                m_uiOptions[i].SetAlpha(0);
                m_uiOptions[i].gameObject.SetActive(false);
            }

            SetState(eState.ScrollingText);
        }
        public Conversation Deserialize()
        {
            // Deserialize an editor-version (containing all info) that
            // we will use to construct the user-facing Conversation data structure.
            EditableConversation ec = this.DeserializeForEditor();

            // Create a conversation.
            Conversation conversation = new Conversation();
            // Create a dictionary to store our created nodes by UID
            Dictionary <int, SpeechNode> dialogues = new Dictionary <int, SpeechNode>();
            Dictionary <int, OptionNode> options   = new Dictionary <int, OptionNode>();

            // Create a Dialogue and Option node for each in the conversation
            // Put them in the dictionary
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                SpeechNode node = new SpeechNode();
                node.Name = ec.SpeechNodes[i].Name;
                node.Text = ec.SpeechNodes[i].Text;
                node.AutomaticallyAdvance           = ec.SpeechNodes[i].AdvanceDialogueAutomatically;
                node.AutoAdvanceShouldDisplayOption = ec.SpeechNodes[i].AutoAdvanceShouldDisplayOption;
                node.TimeUntilAdvance = ec.SpeechNodes[i].TimeUntilAdvance;
                node.TMPFont          = ec.SpeechNodes[i].TMPFont;
                node.Icon             = ec.SpeechNodes[i].Icon;
                node.Audio            = ec.SpeechNodes[i].Audio;
                node.Volume           = ec.SpeechNodes[i].Volume;
                node.Options          = new List <OptionNode>();
                if (this.GetNodeData(ec.SpeechNodes[i].ID) != null)
                {
                    node.Event = this.GetNodeData(ec.SpeechNodes[i].ID).Event;
                }

                dialogues.Add(ec.SpeechNodes[i].ID, node);
            }
            for (int i = 0; i < ec.Options.Count; i++)
            {
                OptionNode node = new OptionNode();
                node.Text    = ec.Options[i].Text;
                node.TMPFont = ec.Options[i].TMPFont;

                options.Add(ec.Options[i].ID, node);
            }

            // Now that we have every node in the dictionary, reconstruct the tree
            // And also look for the root
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                // Connect dialogue to options
                for (int j = 0; j < ec.SpeechNodes[i].OptionUIDs.Count; j++)
                {
                    dialogues[ec.SpeechNodes[i].ID].Options.Add(options[ec.SpeechNodes[i].OptionUIDs[j]]);
                }

                // Connect dialogue to following dialogue
                if (ec.SpeechNodes[i].SpeechUID != EditableConversation.INVALID_UID)
                {
                    dialogues[ec.SpeechNodes[i].ID].Dialogue = dialogues[ec.SpeechNodes[i].SpeechUID];
                }

                // Check if root
                if (ec.SpeechNodes[i].EditorInfo.isRoot)
                {
                    conversation.Root = dialogues[ec.SpeechNodes[i].ID];
                }
            }

            for (int i = 0; i < ec.Options.Count; i++)
            {
                // Connect option to following dialogue
                if (dialogues.ContainsKey(ec.Options[i].SpeechUID))
                {
                    options[ec.Options[i].ID].Dialogue = dialogues[ec.Options[i].SpeechUID];
                }
            }

            return(conversation);
        }