Accessing values of variables from Dialogue Databases that are instantiated at runtime

Announcements, support questions, and discussion for the Dialogue System.
Sternutation
Posts: 22
Joined: Wed Aug 19, 2020 2:44 pm

Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Sternutation »

Hello,

I am new here, and to using the DialogueSystem.

I was wondering about what is the correct procedure for accessing the values of variables that are present in Dialogue Databases that have been cloned/instantiated at runtime.

I have utilized the method given in https://www.pixelcrushers.com/phpbb/vie ... php?t=2321 to clone the database and assign unique ids to its elements. I utilized the DialogueMerger method as I need to instantiate multiple databases at runtime.

Now I need to access the values of variables from within these cloned databases. My problem is that I cannot simply use DialogueLua.GetVariable(stringName) as, due to the effects of instantiating multiple databases, each clone will have the same names for their variables, even if they have been assigned unique ids as a result of utilizing DialogueMerger. Is there a way of using DialogueLua to get a variable from a specific database?

I played about with DialogueDatabase.GetVariable() but that only allows me to access the initial values or the name of the variable in the database.
Last edited by Sternutation on Mon Aug 24, 2020 5:10 pm, edited 2 times in total.
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Tony Li »

Hi,

Thanks for using the Dialogue System!

Variables must have unique names across databases. At runtime, all database content is merged into a single "master database" in memory.

What is the purpose of cloning your databases? Perhaps I can suggest an easier approach.
Sternutation
Posts: 22
Joined: Wed Aug 19, 2020 2:44 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Sternutation »

Hello,

Thanks for replying. Interesting, I was not aware of the fact that variables must have unique names across all databases.

In that case, I will need to rollback on an approach that I was using for an affinity system. The issue is, I need certain randomly generated characters to reuse the same dialogue as each other but have different responses based around their affinity with the player. These responses will be determined by a variety of factors, but one of those was affinity.

That is why I was hoping to have it so that the game clones this database for each randomly generated character at runtime, and why I was hoping that the variables are duplicated, but it turns out that is not the case. I was hoping to use a relationship variable for checking the conditions for triggering dialogue, but if I make one such variable it cannot be reused for other generated characters.

In that case, how are affinity systems created using this dialogue system and how can those be leveraged for characters that are generated at runtime?
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Tony Li »

Hi,

One way is to use Love/Hate, which is an asset that's solely about affinity and relationships. But that may be overkill.

The Dialogue System has a simple built-in relationship system that uses some special Lua functions.

From your description, there should be no need to create new databases at runtime. When you create an actor, add it to the Dialogue System's runtime Actor[] table. You can use Lua.Run() to do it compactly, or use DialogueLua.SetActorField() to set fields one by one. Example:

Code: Select all

Lua.Run("Actor['Bob'] = {Name='Bob', Display_Name='Robert Robertson", Age=50, Gender='Male'}");
You can associate a GameObject with this actor by adding a Dialogue Actor component:

Code: Select all

var dialogueActor = BobGO.AddComponent<DialogueActor>();
dialogueActor.actor = "Bob";
When this GameObject is used as the conversation conversant (see Character GameObject Assignments), the Dialogue System will automatically set two variables at the start of the conversation:
  • Variable["Conversant"]: The actor's Display Name ("Robert Robertson").
  • Variable["ConversantIndex"]: The actor's index (key) in the Actor[] table ("Bob").
You can use the [var=Conversant] markup tag in dialogue text:
  • Dialogue Text: "Hi, my name is [var=Conversant]."
Also, instead of referring to the actor explicitly like: Actor["Bob"]
you can refer to the current conversant: Actor[Variable["ConversantIndex"]]

Example:
  • Dialogue Text: "2020's nothing! I remember the Flu of 1918!"
  • Conditions:

    Code: Select all

    Actor[Variable["ConversantIndex"]].Age > 99
You can also use the built-in relationship functions:
  • Dialogue Text: "Thanks for the cake! I've never had a cake that looked like a shoe before."
  • Script:

    Code: Select all

    IncRelationship(Actor[Variable["ConversantIndex"]], Actor["Player"], 5)
If you don't want to use the built-in relationship functions, you can write your own in C# and register them with Lua so you can use them in Conditions and Script fields.

So, putting all this together, you should be able to write general-purpose conversations that can adapt to whatever characters get assigned to the current active instance of the conversation.
Sternutation
Posts: 22
Joined: Wed Aug 19, 2020 2:44 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Sternutation »

Hello,

Thank you so much for this approach! I will use it.


So the solution would be to-

1. Have characters added as Dialogue Actors to the Actor table on spawn.
2. Spawn them with Dialogue System Triggers that start a reusable conversation when spoken to.
3. Use either the built in relationship functions or create my own and register with Lua, to add conditions and scripts to reusable conversations.
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Tony Li »

Yes, exactly. When you create your character GameObject:

1. Create an entry in the Lua Actor[] table (e.g., using Lua.Run) as in my previous reply.

2. Add a Dialogue Actor component to the GameObject, and set its actor property.

3. Add a Dialogue System Trigger component to the GameObject to start a reusable conversation.

4. If you're using a Selector or Proximity Selector on the player to start conversations, also add a Usable component and collider to the character's GameObject.

If you're instantiating a prefab to create your character, it will probably already have a Dialogue Actor, Dialogue System Trigger, Usable, and collider on it, so you'll just need to set the Dialogue Actor's actor property.

Also, inspect the Dialogue Manager GameObject and tick Persistent Data Settings > Include Actor Data. This tells the Dialogue System's save system to include the Actor[] table in saved game data.
Sternutation
Posts: 22
Joined: Wed Aug 19, 2020 2:44 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Sternutation »

Okay, I shall implement this solution. Thanks again for all the help!
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Tony Li »

Happy to help!
Sternutation
Posts: 22
Joined: Wed Aug 19, 2020 2:44 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Sternutation »

Hello,

Apologies for bothering you again but I was wondering in the line-

Code: Select all

Lua.Run("Actor['Bob'] = {Name='Bob', Display_Name='Robert Robertson', Age = 50, Gender = 'Male'}");

Can I replace all of the values in the single quotation marks with C# variables?

For example,

Code: Select all

Lua.Run("Actor['ActorName'] = {Name = 'ActorName', Display_Name = 'ActorDisplayName', Age = 'ActorAge', Gender = 'ActorGender'}");

Where ActorName, ActorDisplayName, ActorAge and ActorGender are all variables being drawn from elsewhere and not being set in this script itself?
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime

Post by Tony Li »

Sure. You're just passing a string to Lua to be parsed as Lua code. You can generate that string however you want. Example:

Code: Select all

string ActorName = "Bob";
string ActorDisplayName = "Robert Robertson";
string Age = 50;
string Gender = "Male";
// (Uses C# 6.0 string interpolation to include variables in string)
string luaScript = $"Actor['{ActorName}'] = \{ Name = '{ActorName}', Display_Name = '{ActorDisplayName}', Age = '{ActorAge}', Gender = '{ActorGender}' \}";
Lua.Run(luaScript);
Post Reply