Procedural characters?

Announcements, support questions, and discussion for the Dialogue System.
timbecile
Posts: 110
Joined: Mon Mar 12, 2018 11:00 pm

Procedural characters?

Post by timbecile »

I was just looking at quest machine and saw that it has procedural quests (which I will be checking out), but I wondered if Dialogue System had a way to create procedural NPCs (to talk and give out those quests)

I am planning a pretty big game world, and I think I'm going to have to fill it with random villages (which will require random NPCs) and then random quests.

Any thoughts on that?
User avatar
Tony Li
Posts: 21070
Joined: Thu Jul 18, 2013 1:27 pm

Re: Procedural characters?

Post by Tony Li »

Hi,

Yes. Since the Dialogue System doesn't tie conversations to specific GameObjects, you can re-use conversations as mentioned in Character GameObject Assignments. You can also leverage variables to customize those conversations.

For example, you can add a Dialogue Actor to each procedurally-generated NPC, and set its actor name to a randomly-generated name. When you start a conversation with this NPC as the conversant, it will use the name set in the Dialogue Actor component. You can show that name in Dialogue Text using [var=Conversant]:
  • Dialogue Text: "Hi, I'm [var=Conversant]!"
You can also set other other variables, reference them in Dialogue Text, and use them in Conditions. For example, say you have a script like this:

Code: Select all

public class CharacterDetails : MonoBehaviour
{
    public string hometown;
    public bool likesRain;
    
    void OnConversationStart(Transform actor)
    {
        DialogueLua.SetVariable("Hometown", hometown);
        DialogueLua.SetVariable("LikesRain", likesRain);
    }
}
Then you can have Dialogue Text like:
  • Dialogue Text: "I'm from [var=Hometown]. We have the best BBQ there."
and you can check Conditions such as:
  • Conditions: Variable["IsRaining"] and Variable["LikesRain"]
  • Dialogue Text: "I love a good downpour. It feels so cleansing."
You can also use RandomElement() to add a little variety:
  • Dialogue Text: "I love a good [lua(RandomElement("downpour|shower|spring rain")]. It feels so cleansing."
timbecile
Posts: 110
Joined: Mon Mar 12, 2018 11:00 pm

Re: Procedural characters?

Post by timbecile »

I think this is exactly what I was hoping for.

So you can randomize some of the words in a conversant text, but can you pull entire conversation trees from somewhere to build a random Dialog Actor or does the Dialog Actor have to be already written?
User avatar
Tony Li
Posts: 21070
Joined: Thu Jul 18, 2013 1:27 pm

Re: Procedural characters?

Post by Tony Li »

You can pull entire conversations. Here are a couple of ways you can approach it:
  • You can set some variables on the NPC, always start the same "hub" conversation for every NPC, and branch to different conversations (or different branches of the same conversation) based on the variable values.
  • Or when you create an NPC you can assign a conversation -- e.g., shopkeeper conversation, wandering villager conversation, bandit conversation, etc.
timbecile
Posts: 110
Joined: Mon Mar 12, 2018 11:00 pm

Re: Procedural characters?

Post by timbecile »

Hi Tony,

I've turned my attention back to this, and am wondering if there is a way to randomly assign conversations. I'm thinking of getting all conversations within a folder (town/type/character) into a list, and then choosing from that list to assign it to a character.

is there a method for doing that?
User avatar
Tony Li
Posts: 21070
Joined: Thu Jul 18, 2013 1:27 pm

Re: Procedural characters?

Post by Tony Li »

Hi,

There are some ways you could do it:

1. Always start the same hub conversation. Link the hub's <START> node to an empty node. Link the empty node to all of the other conversations. Set the Sequence field to:

Code: Select all

required RandomizeNextEntry(); Continue()
If you don't require continue button clicks, you can simplify the Sequence to: RandomizeNextEntry()

2. Or, in a script, randomly assign a value to the Dialogue System Trigger's conversation property. For example, to assign a random conversation whose title starts with "Towns/Cloud Village/":

Code: Select all

List<string> conversations = DialogueManager.masterDatabase.conversations.FindAll(x => x.Title.StartsWith("Towns/Cloud Village/");
GetComponent<DialogueSystemTrigger>().conversation = conversations[Random.Range(0, conversations.Count)];
3. Or make a subclass of DialogueSystemTrigger and override the DoConversationAction() method. Something like:

Code: Select all

protected override void DoConversationAction(Transform actor)
{
    conversation = ((some random conversation title))
    base.DoConversationAction(actor);
}
timbecile
Posts: 110
Joined: Mon Mar 12, 2018 11:00 pm

Re: Procedural characters?

Post by timbecile »

perfect. Option 2 is what I was looking for.

I was going to tie this into the saver system, so is there a way to save that conversation?
User avatar
Tony Li
Posts: 21070
Joined: Thu Jul 18, 2013 1:27 pm

Re: Procedural characters?

Post by Tony Li »

You could write a saver script that saves that conversation title. Example:

Code: Select all

using UnityEngine;
using PixelCrushers;
using PixelCrushers.DialogueSystem;

public class DialogueSystemTriggerConversationSaver : Saver
{
    public override string RecordData()
    {
        return GetComponent<DialogueSystemTrigger>().conversation;
    }
    
    public override void ApplyData(string s)
    {
        if (!string.IsNullOrEmpty(s))
        {
            GetComponent<DialogueSystemTrigger>().conversation = s;
        }
    }
}
timbecile
Posts: 110
Joined: Mon Mar 12, 2018 11:00 pm

Re: Procedural characters?

Post by timbecile »

perfect. thanks!
User avatar
Tony Li
Posts: 21070
Joined: Thu Jul 18, 2013 1:27 pm

Re: Procedural characters?

Post by Tony Li »

Glad to help!
Post Reply