tylerwsavatronix wrote:Hey Tony,
Thanks for the quick reply. We actually bought DS a while ago, but are just now getting around to integrating it (that's my assigned user story ATM).
Thanks for buying the Dialogue System!
tylerwsavatronix wrote:1) I noticed the conversation trigger component only supports 1 conversation at a time. This kind of implies that, but I wanted to get clarification since I'm not familiar with DS (or chatmapper, or any other dialogue system, heh); Is it a best practice to have one conversation tree per character? It makes sense given that conditions on nodes are in LUA and we probably wouldn't want to code up a secondary system to try and sort out which conversation an NPC should belong to at any point in time.
The Dialogue System supports multiple simultaneous conversations. (Tick the Dialogue Manager's Allow Simultaneous Conversations checkbox/set the bool property.) And you can add more than one Conversation Trigger to a GameObject if you want, and control which one fires based on their Conditions.
But, to actually answer your question: Yes, it's easiest to have one conversation character, unless the character has a lot of dialogue. In this case, you might want to split each major topic into a separate conversation. You can link between conversations. You may also find it handy to use forward slashes ("/") in your conversation titles, such as "Fellowship/Gandalf/Birthday", "Fellowship/Gandalf/Moria", "Fellowship/Gandalf/Isengard", etc. The slashes will act as submenus in the dialogue editor and conversation trigger pop-up menus. But ultimately it's really up to how you want to organize it.
tylerwsavatronix wrote:2) In our game, every NPC is unique (no shared dialogue). Given that, could we just make do using the OverrideActorName script and calling DialogueSystem.StartConversation() and (assuming #1 is the right way to do it) be good to go?
Sure, or just pass the correct NPC GameObject to DialogueManager.StartConversation(), such as:
Code: Select all
DialogueManager.StartConversation("My Conversation", player.transform, someNPC.transform);
tylerwsavatronix wrote:3) Is there any component we need to attach to the player in order to tell DS that this gameobject is the player, or just simply use the OverrideActorName component and set its name there to whatever we defined as the Player in the DB?
No special component. Just pass the player to DialogueManager.StartConversation() or use OverrideActorName. However, you may want to add some utility components such as
Set Component Enabled On Dialogue Event to disable player control during conversations or
Set Animator State On Dialogue Event to put the player in an idle animation at the start of the conversation. See
How to Set Up the Player for more info.
tylerwsavatronix wrote:4) We were thinking JSON because we recently moved all our runtime loading to that format instead of XML, but given it's unsupported for DS at the moment, would the best way to handle it be to design in Unity, but export to chat mapper xml and then load that in at runtime (our goal is to allow modders to change/add dialogue)? Could you please point me towards the documentation for importing the xml at runtime?
The static method
ChatMapperProject.Load(filename) loads a Chat Mapper Project. You can use its
ToDialogueDatabase() method to convert it to a dialogue database:
Code: Select all
var myDialogueDatabase = ChatMapperProject.Load(filename).ToDialogueDatabase();
Then you can add it to the runtime environment using
DialogueManager.AddDatabase():
Code: Select all
DialogueManager.AddDatabase(myDialogueDatabase);
However, in practice there's usually one extra concern. Dialogue database content (actors, conversations, etc.) are all referenced by ID numbers. When you create a dialogue database, the first conversation is assigned ID 1, the second conversation ID 2, etc.
If you create a second dialogue database, its first conversation will also have ID 1, etc.
If you add both databases to the runtime environment, ID 1 will be ambiguous because there will be two conversation with that ID number.
When you're creating your databases at design time in the editor, you can use the
Unique ID Tool to adjust the ID numbers so they're unique across multiple databases.
If you're creating databases at runtime, however, the solution is to use the
DatabaseMerger class to merge the contents of one database into another, which guarantees that everything's assigned a unique ID.
tylerwsavatronix wrote:5) Could you also please point me towards the documentation for creating a DB in code? Also what type would I use in the generic Resources.Load<>() to load a db at runtime?
The type is
DialogueDatabase. It's a
ScriptableObject asset.
Here's some example code to create a database. It uses a utility class named
Template.
Code: Select all
// Create database:
var database = ScriptableObject.CreateInstance<DialogueDatabase>();
// Create a template, which provides helper methods for creating database content:
var template = Template.FromDefault();
// Create actors:
int playerID = 1;
int npcID = 2;
database.actors.Add(template.CreateActor(playerID, "Player", true));
database.actors.Add(template.CreateActor(npcID, "NPC", false));
// Create a conversation: [ID 0=START] --> [ID 1=Hello]
int conversationID = 1;
var conversationTitle = "My Conversation";
var conversation = template.CreateConversation(conversationID, conversationTitle);
conversation.ActorID = playerID;
conversation.ConversantID = npcID;
database.conversations.Add(conversation);
// START node: (Every conversation starts with a START node with ID 0)
var startNode = template.CreateDialogueEntry(0, conversation.id, "START");
node.ActorID = playerID;
node.ConversantID = npcID;
startNode.Sequence = "None()"; // START node usually shouldn't play a sequence.
conversation.dialogueEntries.Add(startNode);
// Actual dialogue node ("Hello") with ID 1:
var helloNode = template.CreateDialogueEntry(1, conversation.id, string.Empty);
helloNode.ActorID = npcID; // NPC speaks this line.
helloNode.ConversantID = playerID;
helloNode.DialogueText = "Hello";
conversation.dialogueEntries.Add(helloNode);
// Link from START to Hello:
var link = new Link(conversation.id, startNode.id, conversation.id, node.id);
startNode.outgoingLinks.Add(link);
// And what the heck - might as well add it to the runtime environment and play it:
DialogueManager.AddDatabase(database);
DialogueManager.StartConversation(conversationTitle);