SimpleDialog.cs

DataStructures: List, Queue - For ConversationEntries

Now, we just have to figure out how to write the code logic. We need a List of ConversationEntry items, then we need to display them sequentially when the next button has been clicked.

Unity can display for editing, both List< string >, or array: string[] in the inspector below.

List< T > is part of the System.Collections.Generic Namespace in C#. MSDN Reference

Queue< T > is a data structure that operates like a queue / waiting line. It will make it easy to remove each sequential dialog item from the collection so it can be displayed in sequence.MSDN Reference

SimpleDialog.cs

(See complete code at bottom of page)

We will have several different versions of classes that can be used for creating and managing conversations. Subsequent versions will have slightly more complex code, but they will be easier to use in Unity.

  • Declare Object Reference Variables - ConversationEntry

    • In the code below we specify that the List< T > and Queue< T > will both be collections of ConversationEntry objects.

    private Queue<ConversationEntry> conversationsQueue = new Queue<ConversationEntry>();
    public List<ConversationEntry> conversations; //initialized by Unity in Inspector
  • Declare object reference variables for the components we'll interact with.

    public Button openButton;
    public CanvasGroup nextPanelToOpen;
    public bool showOnStart = false;

    //find in children
    private Button nextButton; //only 1 child button
    private Text dialogText;   //find as a child - Hierarchy order mattersprivate CanvasGroup dialogCG;  //Canvas Group on top level - script attached to this Panel
    private Text speakerText;  //find as a child - Hierarchy order matters
    private CanvasGroup dialogCG; //top level panel
  • Start: Initialize Object Reference Variables

    The following logic would be located in the Unity Start( ) event function for this script that's attached to the panel gameObject:

 // Use this for initialization
    void Start()
    {
        dialogCG = GetComponent<CanvasGroup>();
    //Find all children Text elements of current Panel GameObject
        Text[] textChildren = GetComponentsInChildren<Text>();
        dialogText = textChildren[0]; //first child Text
        speakerText = textChildren[2]; //3rd child Text

        InitializeDialog(); //populate Queue, set initial conversation values

        nextButton = GetComponentInChildren<Button>();
        nextButton.onClick.AddListener(GetNextDialog);
        if (!showOnStart) //Should this be hidden at Start
        {   //is there a button to display panel
            if (openButton != null)
            {
            openButton.onClick.AddListener(ShowDialogPanel);
            }
            Utility.HideCG(dialogCG); //hide initially
        }
        else //show on start
        {
            Utility.ShowCG(dialogCG);
        }

    }//end start
  • GetComponentsInChildren< Text >()See section below for details

  • Populate the queue data structure

Initialize DialogQueue

In the code below we specify that the List< T > and Queue< T > will both be collections of ConversationEntry objects.

void InitializeDialog()
    {
        foreach( ConversationEntry item in conversations)
        {
            conversationsQueue.Enqueue(item); //put each string -item in the queue
        }
        GetNextDialog();  //get first item
    }

GetNextDialog Method

The nextButton allows the user to move forward through the dialogue items. In the Start( ) method, we configured the nextButton's onClick method to execute the GetNextDialog method each time it is clicked. The code below shows that each time the GetNextDialog method is executed, it first checks to make sure there are items in the queue. Then, the dialogText is updated to display the first item in the queue. The Queue< T > Dequeue( ) method retrieves and removes the item at the front of the queue returns that value so it can be used to set the text value for the dialogText. If there are no more items in the queue, then the panel is hidden, using the Utility class static method: HideCG.

void GetNextDialog()
    {
        if (conversationsQueue.Count > 0)
        {
            ConversationEntry item = conversationsQueue.Dequeue();
            dialogText.text = item.dialogTxt;
            speakerText.text = item.speakerName;
        }
        else { //no more dialog
            if ( nextPanelToOpen != null)
            {
                Utility.ShowCG(nextPanelToOpen);
            }
            Utility.HideCG(dialogCG); //hide the dialog
        } 
    }

    //Helper Method, allows Button-click To Execute Utility.ShowCG( )
    public void ShowDialogPanel()
    {
        Utility.ShowCG(dialogCG);
    }//end function

Unity: GetComponentsInChildren< T >()

The Unity method: GetComponentsInChildren, provides a convenient way to initialize an object reference variable based on the Hierarchy panel's parent-child relationships between gameObjects.

In the code above, we've specified that we want to initialize the Text component reference variable: dialogText, speakerText. Since the current script is on the DialogPanel in our custom prefab, and since there is a UI-Text gameObject that is a child of the DialogPanel, we can access the components on that child object using this method.

Important: Note that this method will find all < T > components while traversing the Parent-child relationships of the gameObject that this script is attached to. So, make sure to order your gameObjects in the hierarchy correctly if you plan to use this method.

Unity also has a similar method: GetComponentsInChildren< T >(), which returns an array of all matching object in children that are ordered according to parent-to children ordering in the hierarchy.Unity Manual

SimpleDialog.cs Complete Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SimpleDialog : MonoBehaviour
{

    public Button openButton;
    public CanvasGroup nextPanelToOpen;
    public bool showOnStart = false;

    //find in children
    private Button nextButton; //only 1 child button
    private Text dialogText;   //find as a child - Hierarchy order mattersprivate CanvasGroup dialogCG;  //Canvas Group on top level - script attached to this Panel
    private Text speakerText;  //find as a child - Hierarchy order matters
    private CanvasGroup dialogCG; //top level panel

    private Queue<ConversationEntry> conversationsQueue = new Queue<ConversationEntry>();
    public List<ConversationEntry> conversations;

    // Use this for initialization
    void Start()
    {
        dialogCG = GetComponent<CanvasGroup>();
        Text[] textChildren = GetComponentsInChildren<Text>();
        dialogText = textChildren[0];
        speakerText = textChildren[2];

        InitializeDialog();

        nextButton = GetComponentInChildren<Button>();
        nextButton.onClick.AddListener(GetNextDialog);
        if (!showOnStart)
        {   //click button to display panel
            if (openButton != null)
            {
                openButton.onClick.AddListener(ShowDialogPanel);
            }
            Utility.HideCG(dialogCG); //hide initially
        }
        else //show on start
        {
            Utility.ShowCG(dialogCG);
        }

    }//end start

    void InitializeDialog()
    {
        foreach (ConversationEntry item in conversations)
        {
            conversationsQueue.Enqueue(item); //put each string -item in the queue
        }
        GetNextDialog();  //get first item
    }

    void GetNextDialog()
    {
        if (conversationsQueue.Count > 0)
        {
            ConversationEntry item = conversationsQueue.Dequeue();
            dialogText.text = item.dialogTxt;
            speakerText.text = item.speakerName;
            
        }
        else
        { //no more dialog
            if (nextPanelToOpen != null)
            {
                //Before displaying nextPanelToOpen, if it's OptionPanel, get the buttons set
                  Utility.ShowCG(nextPanelToOpen);
            }
            Utility.HideCG(dialogCG); //hide the dialog
        }
    }

    public void StartInitialDialog()
    {
        Utility.ShowCG(dialogCG);
        Debug.Log("Show and Starting Dialog");
        
    }

    public void ShowDialogPanel()
    {
        Utility.ShowCG(dialogCG);
    }//end function

} //end class

Last updated