We added a Dialogue System, a Unity 3d asset, to our game Erwin’s timewarp for conversations between characters. We are using this Dialogue System you can find in the assetstore because it has a great API support and is UI independent which was really important for us.

With the asset it is possible to create the conversations for the characters in a database, you don’t need to write code for this. So the first thing you do after importing the Dialogue System asset is:

Creating a new database

Note: If you have an existing project you want to import the package into, make sure you are using Mixed Serialization in the Editor Settings before the import. After importing you can use any Serialization type:

Project Settings for Editor

1. Open Project Settings for Editor

Mixed Serialization

2. Select Mixed Serialization

Now we create the database: Right click in the Project View and choose Create > Dialogue System > Dialogue Database.

Creating a new Dialogue database

Creating a new Dialogue database

We named the database TalkDB but you can choose any name you like.

The next step is to define the Actors, the participants of conversations, normally the player and an NPC (non player character).

Adding actors to the Dialogue database

Adding actors to the Dialogue database

You can see that we added two Actors: Erwin is the player, the main character of Erwin’s timewarp, so the IsPlayer-property is set to true. The other character is Herbert, a nice and friendly monster, he is an NPC.

Add conversation

Let’s add our first conversation between Erwin and Herbert. Select the Conversation Tab choose New Conversation:

Create a new conversation

Create a new conversation

Then you can add a name for the conversation:

Name for a conversation

Name for a conversation

and finally define the dialog entries by creating nodes:

Create a new child Dialogue Editor

Create a new child Dialogue Editor

The method is very intuitive and perhaps you know this kind of node creation from the Unity 3D animation controller editor.

Create child nodes, links from the parent nodes to the child nodes are added automatically. Our first conversation looks like this. For each node you have to add a title and a Dialog text. The dialog text will be displayed in the UI when the conversation is started.

Our first conversation now looks like this, the grey nodes represent the entries for the NPC, the blue nodes the ones for the player.

The conversation in Dialogue editor

The conversation in Dialogue editor

Add a Dialog Manager

A dialog manager is a GameObject that manages the interaction between the database and the actors, it coordinates the conversations. You can add it by clicking Window > Dialogue System > Wizards > Dialogue Manager. The new GameObject is added to the scene now. Select the Dialog Manager window and assign the database you created (in our case TalkDB).

Choose the UI

There are many Prefabs for the conversation’s UI. You can add a predefined UI to the Dialogue UI property of the Dialogue Manager object. The Preafabs are located in the folder Prefabs/Unity Dialogue UIs.

Starting the conversation

At this point you can start the conversation. There is a way to configure the actors (player and NPC) to start the conversation without coding – but we want to have more control and therefore use the API of Dialogue System to start conversations when the player is near an NPC, here is our C# Script:

private bool _conversationActive = false;

// Update is called once per frame
protected new void Update()
{
    if (GameManager.Instance.IsDead)
        return;

    //Get velocity in world-space
    Vector3 velocity;
    if (target != null)
    {
        if (DialogueManager.IsConversationActive)
            return;

        // Calculate desired velocity
        Vector3 dir = CalculateVelocity(GetFeetPosition());

        // Rotate towards targetDirection (filled in by CalculateVelocity)
        RotateTowards(targetDirection);

        dir.y = 0.0f;

        float dist = Vector3.Distance(PlayerController.Instance.transform.position, tr.position);

        // We are near the monster => monster introduces himself
        if (dist < 3.0f)
        {

            if(!_conversationActive)
                DialogueManager.StartConversation("Meeting_Herbert");

            _conversationActive = true;
        }
        else
        {
            _conversationActive = false;
        }
    }
    else
    {
        velocity = Vector3.zero;
    }
}

As you can see we use a variable called (_conversationActive) to lock the call StartConversation but this is a bit ugly, so we wrote a class to wrap this up more nicely:

public class DialogueUtil
{
    private bool _conversationActive = false;

    #region Singleton init

    private static volatile DialogueUtil instance;
    private static object syncRoot = new System.Object();

    private DialogueUtil() { }

    public static DialogueUtil Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new DialogueUtil();
                }
            }

            return instance;
        }
    }

    #endregion

    /// <summary>
    /// This methods starts a conversation if the distance from a player to an npc is less then the param "distance"
    /// </summary>
    /// <param name="name">name of the conversation</param>
    /// <param name="distance">distance player to npc</param>
    /// <param name="player">transform of the player</param>
    /// <param name="npc">transform of npc</param>
    public void StartConversationForDistance(string name, float distance, Transform player, Transform npc)
    {
        float dist = Vector3.Distance(player.position, npc.position);

        // We are near the monster => monster introduces himself
        if (dist < distance)
        {
            if (!_conversationActive)
            {
                DialogueManager.StartConversation(name);

                _conversationActive = true;
            }
        }
        else
        {
            _conversationActive = false;
        }
    }
}

Now you can start the conversation when the distance is less then a certain number with one line of code:

DialogueUtil.Instance.StartConversationForDistance("Meeting_Herbert", 
3.0f, thePlayerTransform, theNPCTransform);

And this is our result, with a custom Unity UI (how to create custom UIs can be found well explained in the Dialog System Documentation):

Herbert starts conversation

Herbert starts conversation

Erwin answers the question

Erwin answers the question

End of conversation

End of conversation

If you have any questions feel free to ask, we can also give you tips on how to build the custom UI with Unity’s new UI system, this is our setup of the Canvas:

A custom UI for conversations

A custom UI for conversations

Custom UI: Response buttons

Custom UI: Response buttons

(Visited 572 times, 4 visits today)