Beginner trying to understand Conversations & NPCs talking to Each Other

Announcements, support questions, and discussion for the Dialogue System.
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

Hi there! I’ve recently bought the Dialog System for Unity, and I would like some overall guidance on what to use specifically in the plugin overall, as this is the first time I’ll be using this. I’m a novice programmer, so I’m not as proficient as I would like to be, which is why I’m asking for clarification.

I’m currently in the midst of making a card game, where different opponents can converse with each other at the table. While the player is one of the potential conversants in the game, the emphasis is on the other characters interacting with each other, which is a bit of an unusual situation that I’m not sure how to reflect using the Dialog system.

While I think something like barks could work for more short text reactions, I’m not as sure how I should be implementing the specific features I’m looking for.

1. I want the players to be able, after a turn starts (and after a random amount of time has passed, so that they’re not constantly talking), to start conversations with each other. These conversations are brief, but are tied to specific pairs of characters being present at the table; which I’m not sure how to keep track of. Currently, the AI player characters are initialized through a ScriptableObject containing their data being pasted onto a prefab that holds standard character properties. Should I be tying some kind of dialog prefab in to the ScriptableObjects so that the DialogManager knows which players are physically present? Are ScriptableObjects able to hold what ‘Actor’/Conversant that the character should be?

2. These conversations should probably check to see how long it’s been since they last actually talked about it, so that conversations ideally aren’t repeated over and over. I’m guessing a variable can keep track of this, but I wouldn’t know how to make it on a per-conversational basis, since it would presumably randomly choose between the characters actually present at the table (and all the combination conversations they have)

3. I’ll eventually have to make an external system that keeps track of the character’s relationship values (and the corresponding cutscenes that play when specific values are reached, like the Fire Emblem supports), but I want there to be a sort of ‘cutscene viewer’, where I can play the same cutscenes back in a simulated way outside of the actual contexts where the scenes happened.

The videos on the website have been decently informative, but it can be difficult interpreting how to put all the pieces together in the actual game. There’s a lot of moving parts, and in particular, I’m not as familiar as I would like to be on Conversations specifically, and what I can do to achieve some of my desired goals in-game. I don't want to cram too much into the same forum post, but to give the gist of it, I'm just not sure how to use Conversations properly even after watching the videos. What happens if there's dozens and dozens of conversations, how is it going to be sorted for easy navigation? How do I even delete them from the database? Am I meant to have multiple or just one Database?

I guess if I wanted to have the characters react to specific occurrences during the card game, I’d tie an invoke on the script for when these things happen, so that an appropriate bark can be displayed via a listener?

If there’s any advice others can give me on how to get started, I’d really appreciate it! I can provide further clarification on what I'm trying to do if needed, since I'm pretty new to this plugin, & don't have as much programming literacy to grasp some of the concepts immediately.
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by Tony Li »

Hi,

It's probably best to keep track of which characters are present outside of the Dialogue System.

If each character has its own ScriptableObject asset, you can include an actor dropdown dropdown in your ScriptableObject script by using an [ActorPopup] attribute. Rough example:

Code: Select all

public Character : ScriptableObject
{
    [ActorPopup(true)] public string actor;
    public GameObject prefab;
    // ... other info ...
}
Add a Dialogue Actor component to your character prefab. When you instantiate the prefab, set the Dialogue Actor's actor property. You can also set other properties such as dialogueUISettings.subtitlePanelNumber and subtitleColor.

You could also have a separate type of ScriptableObject asset in which you can specify an actor, conversant, and conversation to play, such as:

Code: Select all

public class PotentialConversation : ScriptableObject
{
    public Character actor;
    public Character conversant;
    [ConversationPopup(true)] public string conversation;
    // ... maybe other conditions here, too ...
}
You could include other conditions in this ScriptableObject -- for example, if the player has played a certain card, or if another character has been beaten out of the game.

Then, when you want to play a conversation, you can choose one of these ScriptableObject assets and play the specified conversation.

Use DS variables to track how long it's been. Use variable groups to organize them.

For relationship values, you could use the Dialogue System's Relationship Functions (part of Logic & Lua). And for cutscenes you can use the Dialogue System's cutscene sequence system. It also integrates with Timeline and Slate if you prefer those.

> What happens if there's dozens and dozens of conversations, how is it going to be sorted for easy navigation?

Use forward slashes to organize conversations into submenus. Example:
  • Companions/Robot Butler/At Your Service
  • Companions/Robot Butler/Malfunction
  • Desert/Scavenger
  • Desert/Scorpion Herder
  • Jungle/Shaman, etc.
> How do I even delete them from the database?

Inspect a conversation and select Menu > Delete Conversation, or right-click on empty canvas space and select Delete Conversation from the pop-up menu.

> Am I meant to have multiple or just one Database?

One database is much easier to manage. See: Working With Multiple Databases for more info.

> I guess if I wanted to have the characters react to specific occurrences during the card game, I’d tie an invoke on the script for when these things happen, so that an appropriate bark can be displayed via a listener?

Maybe run a method whenever something interesting occurs. In this method, check all of the PotentialConversations to see if one of them should run. A very rough example:

Code: Select all

public class ConversationRunner : MonoBehaviour
{
    public List<PotentialConversation> potentialConversations; // Assign assets here.
    
    public void CharacterDidSomething(Character character)
    {
        if (DialogueManager.isConversationActive) return; // Skip if already playing another conversation.
        
        foreach (var potentialConversation in potentialConversations)
        {
            if (potentialConversation.actor == character &&
                IsCharacterPresent(potentialConversation.conversant) && 
                AreConditionsTrue(potentialConversation))
            {
                DialogueManager.StartConversation(potentialConversation.conversation);
                break;
            }
        }
    }
}
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

Hi! Thanks for the in-depth response. If it’s alright, there’s more questions that come to mind due to my inexperience with the system, some of which pertaining to the solutions you’ve presented in this thread.

While the Dialog Actor component seems quite useful for ensuring that a specific prefab is recognised as a given character, I’m sorry to say that I’m not sure how to even get the most basic means of interaction ready.
With the ‘PotentialConversation’ scriptable object script you’ve conceptualized here; is the most effective way to create conversations for these characters is to make a prefab for every single conversation, then plug in the requisite values?
At first, I was considering using the character prefabs and having their triggers play the conversation, but none of the triggers presented in the Dialog System Trigger components seem to be suited for this.

I guess if I had a list of the prefabs, I could have a trigger elsewhere, such as a button or a gamestate change call the Dialog System in order to play a conversation that was part of the list of prefabs? Maybe part of the way to do it is to have a list of these prefab conversations on the character in question.

There's probably a way I could create these through a CreateAssetMenu to streamline it, but I'm just checking/asking if the prefab method is the best way to handle this.


Given that the 'way' conversations are meant to be more like discussions between two NPC characters (IE, akin to the Poker Night at the Inventory games, where the Player doesn't need to make any inputs/the conversation just happens automatically)... if I had one central conversation with several branches like a Bark (ie, multiple child nodes from the start node), does the conversation then randomly choose which one to play? I imagine I can then tell the specific child nodes to keep track of variables within the Dialog System, so if that one's already been played, it won't go into that branch?
(I hope you don't mind me asking, but I'm also unsure how best to access the DS variables through scripts if I need to set them.)

Also, one functionality I'm curious about how to create is being able to resume conversations if they're interrupted - ie, if some characters do a dramatic play, any on-going conversations would be interrupted by exclamations of shock. I've seen a few games do a way where, there's a 'So anyway', or 'Like I was saying..." phrase, before the conversation returns back to the main back and forth between two characters. How would you go about creating this kind of feature within the Dialog System framework?
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by Tony Li »

Hi,

I suggested PotentialConversation ScriptableObject assets because it seems like a nice way to keep things modular. Each potential conversation (specific actor + specific conversant + specific conversation) would be a separate PotentialConversation asset. As you mentioned, if you put [CreateAssetMenu] in the line above your PotentialConversation class name, Unity will make a menu item for it.

Then you'd have a ConversationRunner MonoBehaviour in your scene that has a list of all PotentialConversation assets. When a character does something, call the CharacterDidSomething() method. This method would check all of the PotentialConversation assets to find one that's currently valid. If it finds one, it would play it.

---

To access DS variables in your code, use the DialogueLua class.

---

There are two ways to interrupt conversations:

1. To dip into another conversation tree branch and then pop back out and resume where you left off, use the Conversation Position Stack. It sounds like this is what you want to do.

2. However, another option is to stop the conversation entirely, call DialogueManager.StopConversation(). Save the current conversation info first. Then you can resume it afterward. Example:

Code: Select all

string conversationTitle = DialogueManager.lastConversationStarted;
int entryID = DialogueManager.currentConversationState.subtitle.dialogueEntry.id;
DialogueManager.StopConversation();
To resume:

Code: Select all

DialogueManager.StartConversation(conversationTitle, null, null, entryID);
The line above passes null for the actor & conversant transforms, which will tell the Dialogue System to find them via their Dialogue Actor components.
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

Hi, just another thing I wanted to ask - about the DS variables:
What do I do if my projects currently do not have any implementation of Lua at all? Admittedly, I've never even heard of Lua interacting with Unity up until this point, as all of my scripts up to this point have been created in C#.

I'm not even sure how to interface some of the DS variables into my existing scripts for basic features like turning booleans on and off externally, whether using Lua or not.
I can try to learn some, but I'm just concerned about not being able to do simple features like the basic features I've mentioned above.

EDIT: I now see that there's a page specifically on integrating C# with Lua, I'll check that out first, but I'll post a different set of questions instead.
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

I have a few more questions since I want to make absolutely sure that I’m applying the mechanics of this plugin properly for the purposes of my game. I’ll likely have to ask even more after I get this functioning, since right now, I’m still yet to create a functioning system in the way I’d like for it to work.

While the Pop-Up Conversation triggers seem interesting, I’m not sure they simulate the kind of conversations I’m trying to go for; automatic conversations that play out over a few seconds without needing the player’s input – almost like automatic barks or subtitles (just without the voice acting). Do they automatically play if the player’s input is never asked for/If the two actors don’t involve the player? (Is the default Player actor therefore the one that has interactivity tied to it?)
The [ActorPopup(true)] and [ConversationPopup(true)] types, if I’m interpreting it right, is it basically interpreting a string as a conversation or Actor that exists within a database?

So if I wanted a conversation between Alice and Bob specifically (called ‘AlicebobConvo’), then I’d have the actor and conversants be “Alice”, and “Bob, with the “AliceBobConvo” as the conversation variable?
I’m not sure about that, in part because I wouldn’t know how the script would know which DialogDatabase to draw from, outside of the DialogManager having an existing one in-scene.
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by Tony Li »

2linescrossed wrote: Wed Jun 14, 2023 3:46 amWhile the Pop-Up Conversation triggers seem interesting, I’m not sure they simulate the kind of conversations I’m trying to go for; automatic conversations that play out over a few seconds without needing the player’s input – almost like automatic barks or subtitles (just without the voice acting). Do they automatically play if the player’s input is never asked for/If the two actors don’t involve the player? (Is the default Player actor therefore the one that has interactivity tied to it?)
Yes, if the conversations only involve NPCs, then it will never show a player response menu. The NPCs will hold the conversation themselves. However, if you've set the Dialogue Manager's Subtitle Settings > Continue Button to Always, the dialogue UI will wait for the player to click a continue button to read the next NPC line. If you want the conversation to play without any player interaction, leave Continue Button set to Never.
2linescrossed wrote: Wed Jun 14, 2023 3:46 amThe [ActorPopup(true)] and [ConversationPopup(true)] types, if I’m interpreting it right, is it basically interpreting a string as a conversation or Actor that exists within a database?
Yes.
2linescrossed wrote: Wed Jun 14, 2023 3:46 amSo if I wanted a conversation between Alice and Bob specifically (called ‘AlicebobConvo’), then I’d have the actor and conversants be “Alice”, and “Bob, with the “AliceBobConvo” as the conversation variable?
Ideally, you'll have just one dialogue database, assigned to the Dialogue Manager GameObject's Initial Database field. (This is by far the easiest and most common setup.) You can save a copy of your Dialogue Manager GameObject as a prefab variant and put it in all of your scenes to make it easier to playtest scenes individually.
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

Hello! Another simple question this time;
How do you get 'speaker SFX' playing for each conversation?

There's two styles that come to mind - the Inscryption/Papers Please style where each line of dialog has a singular sound effect at the start, and the Banjo Kazooie/many indie games style where every single letter is punctuated with a brief SFX, like a typewriter.

For that matter, there's also the matter of some characters needing multiple different SFX for their words, or slowing down specific conversations to fit the mood. Is this done through the Lua scripting parts of the plugin?
I'd appreciate feedback as usual. Thank you!
User avatar
Tony Li
Posts: 22112
Joined: Thu Jul 18, 2013 1:27 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by Tony Li »

Hi,

No need for Lua.

The Banjo Kazooie style is generally called "mumble speak." To set up mumble speak, assign audio clips to the subtitle text's typewriter effect > Audio Clip and Al

If you want to play different audio clips for each actor, see How To: Vary Character Mumble Speak With Typewriter Effect.

---

To play a single audio clip when the typewriter starts, add a script with an OnConversationLine() method to the actor. Something like:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;
public class PlayAudioOnConversationLine : MonoBehaviour
{
    public AudioClip audioClip;
    
    void OnConversationLine(Subtitle subtitle)
    {
        if (subtitle.speakerInfo.transform == this.transform) AudioSource.PlayClipAtPoint(audioClip, transform.position);
    }
}
---

If you want to play voice acted audio, on the other hand, see the Cutscene Sequence Tutorials.
2linescrossed
Posts: 47
Joined: Tue May 16, 2023 10:37 pm

Re: Beginner trying to understand Conversations & NPCs talking to Each Other

Post by 2linescrossed »

Hi, thanks for the continued in-depth help with all of this! Thanks to your info, I've been making steady progress.

I'm currently looking into barks, as a means of properly integrating the 'conversation interruptions' that I want to properly do.

Previously when we discussed this concept, the approach you recommended was to dip into another conversation tree, but that's not what I'm actually trying to do here, I'll try to go into a bit more depth:

The idea is that it's meant to simulate people sitting at a table playing card games, casually talking to one-another (one conversation at a time). So far, I'm able to get the system to play conversations using a list, then feeding it to a function that tells the conversation manager to play the selected conversation. Very nice.


So, the next step I'm aiming for is to be able to dramatically interrupt conversations when a player does something notable, such as going all in. Characters would make a surprised exclamation, then, after all of the necessary phrases resolve (ie, complaints about losing, so on), the character's conversation transitions to a 'So anyway' or 'Picking up where I left off', before continuing the conversation.

The second proposed option of saving the dialogEntry ID seems like the one that's ideal for this, though there are a few questions I have that I'd want to have clarified, thanks!
  • How do I check if any conversations are currently playing before playing barks? I guess this should be an easy check, I just don't know the right command for it.
  • How do I trigger barks the same way that dialogManager.StartConversation(conversationName) works? While barks are tied more to players than the table as a whole, necessitating the Dialog System Triggers, I don't know what the ideal way to set it up is, as there's times where I want characters to respond individually (IE, ending their turn, folding, checking), versus simultaneously (the big dramatic moments).
Thanks in advance.
Post Reply