Page 1 of 3
Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Wed Aug 19, 2020 3:27 pm
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.
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Wed Aug 19, 2020 4:18 pm
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.
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 1:16 pm
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?
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 2:03 pm
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.
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 2:54 pm
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.
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 3:03 pm
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.
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 3:06 pm
by Sternutation
Okay, I shall implement this solution. Thanks again for all the help!
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 3:30 pm
by Tony Li
Happy to help!
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 4:25 pm
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?
Re: Accessing values of variables from Dialogue Databases that are instantiated at runtime
Posted: Thu Aug 20, 2020 5:02 pm
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);