Hi,
Thanks for clarifying.
Runtime-Generated Actors:
You can add a new database for each actor. These databases only need to contain the new actor. Here are general-purpose methods to add and remove new actors at runtime:
Code: Select all
Dictionary<string, DialogueDatabase> actorDatabases = new Dictionary<string, DialogueDatabase>();
public void AddActor(string actorName, string personality)
{
// Determine a unique actor ID:
int highestExistingID = 1;
foreach (var existingActor in DialogueManager.masterDatabase.actors)
{
highestExistingID = Mathf.Max(highestExistingID, existingActor.id);
}
int actorID = highestExistingID + 1;
// Create a database:
var database = ScriptableObject.CreateInstance<DialogueDatabase>();
// Keep track of the database so we can remove it later:
actorDatabases.Add(actorName, database);
// Create actor:
var template = Template.FromDefault();
var actor = template.CreateActor(actorID, actorName, false);
// Add custom fields:
actor.fields.Add(new Field("Personality", personality, FieldType.Text));
// Add this actor to the temporary database:
database.actors.Add(actor);
// Add our new database to the master database:
DialogueManager.AddDatabase(database);
}
public void RemoveActor(string actorName)
{
if (actorDatabases.ContainsKey(actorName))
{
var database = actorDatabases[actorName];
DialogueManager.RemoveDatabase(database);
Destroy(database);
actorDatabases.Remove(actorName);
}
}
(I typed this straight into the reply. Please forgive any typos.)
Conversations:
You can write general-purpose conversations and assign the primary NPC at runtime.
I'll usually keep the default starting actor "NPC" in my dialogue database to use for these general-purpose conversations:
Let's say we have two profession conversations, "Baker" and "Hitman". Assign the generic NPC actor as the primary conversant in both conversations:
And let's say you have an NPC named "Adam", represented by a GameObject. Add a
Dialogue Actor component so you can specify which actor this GameObject is associated with.
If you create the NPC at runtime, assign DialogueActor.actor:
Code: Select all
var dialogueActor = newNPC.gameObject.AddComponent<DialogueActor>();
dialogueActor.actor = "Adam";
When starting a conversation, you can tell the Dialogue System to use this GameObject (and its associated actor) as the primary conversant. You can do this using a
Dialogue System Trigger component:
Or using
DialogueManager.StartConversation in script:
Code: Select all
DialogueManager.StartConversation("Baker", player.transform, adam.transform);
Accessing Actor-Specific Fields In Conversations:
Everything in the master database is also in the Dialogue System's runtime Lua environment. For every actor, there's a corresponding Lua table element, such as Actor["Adam"].
Say you've added an actor field named "Personality", as in the example code above. You can check if Adam's personality is "grumpy" in a dialogue entry node by setting its Conditions field to:
Code: Select all
Actor["Adam"].Personality == "grumpy"
This works if the conversation's actor will always be Adam. But you want to allow any actor to use any conversation. In this case, you can't hard-code "Adam" in the Conditions field.
Fortunately, when a conversation starts, the Dialogue System automatically
defines some useful variables. The one you'll need is Variable["ConversantIndex"]. When you start the conversation with Adam assigned as the primary conversant, Variable["ConversantIndex"] will be "Adam". So you can set the Conditions to:
Code: Select all
Actor[Variable["ConversantIndex"]].Personality == "grumpy"
Sorry for the long-winded War & Peace. If you have any questions, just let me know!