Search Unity

[RELEASED] Dialogue System for Unity - easy conversations, quests, and more!

Discussion in 'Assets and Asset Store' started by TonyLi, Oct 12, 2013.

  1. Mr-Nixon

    Mr-Nixon

    Joined:
    Mar 30, 2013
    Posts:
    140
    Much obliged!
    Everything works.
     
  2. Mr-Nixon

    Mr-Nixon

    Joined:
    Mar 30, 2013
    Posts:
    140
    Just one last question: where should I assign my mp3 files of voice-over?

    I bet that is somewhere in manuals but you'd save my time if you could just lead me as you did earlier.
     
  3. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Mr.Nixon - Put them in a folder named Resources (or a subfolder of Resources). Say you put "not_a_crook.mp3" inside a folder Assets/MyGame/Resources/Voiceover/. Then add this to your dialogue entry's Sequence field: AudioWait(Voiceover/not_a_crook)

    If you don't want the dialogue entry to wait for the mp3 to finish, use Audio(Voiceover/not_a_crook)

    You can imagine that this would be a lot of work to do for each dialogue entry. To make it easier, you can use entrytags. Every dialogue entry has a unique entrytag. Name your mp3 files according to their entrytags, which can you get by exporting a Voiceover Script, and put them in a Resources folder. Then you can set your Dialogue Manager's Default Sequence to AudioWait(entrytag) and leave your dialogue entry sequences blank.

    More info:
     
  4. Mr-Nixon

    Mr-Nixon

    Joined:
    Mar 30, 2013
    Posts:
    140
    TonyLi, you're the best.
    I'm going to twitch my work on the dialogues within your System.
    Considering I'm a rookie and it took me only 15 minutes with your instant support to get in, feel free to use it as the promo.
     
    TonyLi likes this.
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Thanks!
     
  6. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    10,145
    Is there a way to find the incoming links to a conversation entry through script?
     
  7. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    Hi, I just purchased the system.
    It was a hard decision but the videos and documentation convinced me.
     
  8. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Murgilod - Do you mean the links that lead into an entry, or the links that go out of an entry?

    The outgoing links are easy. Once you have a dialogue entry, for example:
    Code (csharp):
    1. entry = DialogueManager.MasterDatabase.GetDialogueEntry(conversationID, entryID);
    the outgoing links are in entry.outgoingLinks.

    The incoming links are harder. You'll want to loop through all dialogue entries:
    Code (csharp):
    1. var incomingLinks = new List<Link>();
    2. var conversation = DialogueManager.MasterDatabase.GetConversation(entry.conversationID);
    3. foreach (var otherEntry in conversation.dialogueEntries) {
    4.     foreach (var link in otherEntry.outgoingLinks) {
    5.         if ((link.destinationConversationID == entry.conversationID) &&
    6.             (link.destinationDialogueID == entry.id)) {
    7.             incomingLinks.Add(link);
    8.         }
    9.     }
    10. }
    If your dialogue database has cross-conversation links, you'll want to loop through all dialogue entries in all conversations.

    Thanks! The Dialogue System for Unity is a big system, since dialogue is often a foundational part of many games, so expect a bit of a learning curve. The 5-Minute Ultra-Quick Start Guide will help get you started on the right footing. And don't hesitate to post here or email me directly at tony (at) pixelcrushers.com if you have any questions. I'm here to help!
     
  9. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    Hi,
    If you answered this before in this thread I am sorry. (its 42 pages)

    I want the player to have a conversation with himself.

    IE:
    Captain's log: Star date 52123.12 Today our colony ship left orbit and we are on our own. The election cycle has begun and I am confident I can build the power and economic base to be elected to the Senate.

    [ Election Cycle ] <- leads to a definition of the Election Cycle
    [ End Log ]​

    How do I set this up properly?
    Who should be the actor and who should be the conversant?

    (edit: after thinking about it some)
    Should I set this up as a quest?
     
    Last edited: Oct 26, 2015
  10. CrispyArrow

    CrispyArrow

    Joined:
    Sep 7, 2015
    Posts:
    2
    I have 1 question: Is it unity 5.0 or higher compatible? I see that on a patch note you got rid of deprecation messages for unity 5. but does it work accordingly?
    I need to make sure the product will work for me before I buy it.
     
  11. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Mazak - It looks like it should be a conversation, not a quest. But if this conversation leads to a set of tasks to complete, then adding a quest might also be appropriate.

    For a monologue, set the Actor to the player and leave the Conversant unassigned. Actors and conversants are mostly just used to specify the GameObject transforms for sequencer commands such as Camera(), and to determine the portrait names in the dialogue UI (if your dialogue UI uses portrait names). They're not mandatory.

    Yes, the Dialogue System for Unity is fully compatible with Unity 5.x. It still also fully supports Unity 4.6, but that's mostly to support older projects where studios have locked down their Unity version. Most users are using the Dialogue System with Unity 5.2, 5.1, or 5.0 nowadays.
     
  12. Mr-Nixon

    Mr-Nixon

    Joined:
    Mar 30, 2013
    Posts:
    140
    I’ve just streamed the development of a couple of dialogues from the game on Twitch. It is just preparation of the dialogue tests I wrote with some voiceovers. It illustrates how relatively simple dialogue converts into the data for the game: http://www.twitch.tv/mrnixonbcs/v/22292398 Interesting moments of the test of the real dialogues from the game are on 00:03:36 and 02:21:09.

    The dialogue with Quanton remastered: http://www.twitch.tv/mrnixonbcs/v/22624462
    Through the prologue you will not be forced to repair or/and switch on that VI. But if you do that it will bring that dialog (one from several of Quanton) to life... Thought, I can’t say or judge if that action would be smart or not because I don't know if I would try do that in real life... Anyway it will be up to you to decide.

    Those interfaces you will see are not from the game, they are just for testing. The final one will be:



    A very pleasant surprise: the asset has save system and dialog mechanics as well. Very friendly to NWN 1&2 moders.
     
    Mazak likes this.
  13. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Awesome! Thanks for sharing this. That dude's voice at 00:03:26! I'm jealous. But I shudder to think how many cigarettes he had to smoke backward to get that cool gravelly sound. Very nice voiceovers throughout. If you'd like your project added to the Dialogue System's Games Showcase (more publicity never hurts), please feel free to send me screenshots or a link to a video!
     
  14. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    So I wanna do some unique things with the dialogue interface that the existing UI isn't really suited for. Specifically:
    • Rather than having a singular dialogue box that refreshes with each conversation node, I'd like to have a mask panel with a scroll bar that generates dialogue boxes within it (up to a certain number), with each box pushing each other upwards, allowing players to quickly review previous dialogue even when not in a conversation (say, via a pause menu or the below-mentioned toggled dialogue menu).
    • Being able to toggle the dialogue choice menu at any time, 'pause' or 'slow' game time in the process, allow the player to select a choice and then confirm it by toggling out of the menu.
    • Enable non-verbal choices in a separate interaction menu.
    Any suggestions on how to go about doing these?

    Edit: Now that I think about it, being able to record and review previously executed one-off dialogue sequences might be a nice feature, too.
     
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Candescence - It's actually really easy but requires a bit of scripting. Just make a copy of Scripts/Templates/TemplateDialogueUI.cs and fill in the methods with your code. The comments in each method will tell you what they should do. These methods are defined in the IDialogueUI C# interface. The Dialogue System will work happily with any UI that implements this interface. It doesn't care what the UI does inside those methods; it trusts the UI to handle that. For example, one developer implemented the methods to use speech recognition and text-to-speech for a vision impaired application; it didn't use any visual elements at all.

    You can look at UnityUIDialogueUI.cs for an example. UnityUIDialogueUI builds on top of AbstractDialogueUI, which is an implementation of the IDialogueUI interface that implements some common functionality. This functionality is probably overkill for your needs and adds unnecessary complexity. It'll be simpler to just directly implement the methods indicated in the template, without subclassing AbstractDialogueUI.

    If I can help with anything, let me know. Also feel free to email me at tony (at) pixelcrushers.com if you'd like to send an example project or anything like that.
     
  16. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    Thanks for the response. Yeah, the UnityUIDialogueUI example is a bit overkill and doesn't resemble the template UI script, and I may have to do a bunch of copy-pasting from UnityUIDialogueControls as well, but I suppose I can try and handle it myself.
     
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Sounds good. I'll be here if any questions come up or if you'd like a hand with anything.
     
  18. dittt

    dittt

    Joined:
    May 29, 2013
    Posts:
    20
  19. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @dittt - Yes. You can use whatever graphics you want to use, including speech bubble textures. Many are free, too, such as this free Clker clipart. It's easiest to use Unity's UI system. Once you get familiar with Unity's UI system, you will probably want to use what's called a world space canvas floating above each character's head. I can help you set this up.

    If you want to integrate with Chat UI & Speech Bubbles' scripts, that will require a small amount of scripting. You don't have to do this, though. You can use the Dialogue System for Unity's build-in user interface features and simply add your own speech bubble textures.
     
  20. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    By the way, how do you get the UI script to know when a response has been picked? I know the button itself uses a messenger, but it seems to be limited to its own object.
     
  21. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    In your UI script, add a method called something like "ClickedResponseButton". Then assign this method to your response buttons' On Click events.

    The "ClickedResponseButton" method should call SelectedResponseHandler() and pass the response that corresponds to that button. (The syntax requires a little more than that, but it's documented in the template.)

    UnityUIDialogueUI keeps track of which button corresponds to which response by putting a UnityUIResponseButton script on each button. It sets this script's "response" property.

    For a simpler implementation, you could configure your buttons to send an int parameter to "ClickedResponseButton", where the first button sends 0, the second button sends 1, etc. Something like:
    Code (csharp):
    1. public Button buttons; // Assign your buttons here.
    2.  
    3. private Response[] currentResponses; // Remember the current responses.
    4.  
    5. public void ShowResponses(Subtitle subtitle, Response[] responses, float timeout) {
    6.     // Set up the response menu:
    7.     for (int i = 0; i < buttons.Length; i++) {
    8.         var useThisButton = (i < responses.Length);
    9.         buttons[i].gameObject.SetActive(useThisButton);
    10.         if (useThisButton) buttons[i].GetComponent<Text>().text = responses[i].formattedText.text;
    11.     }
    12.     currentResponses = responses;
    13. }
    14.  
    15. public void ClickedResponseButton(int buttonIndex) {
    16.     // Report the response selection to the Dialogue System:
    17.     var response = currentResponses[buttonIndex];
    18.     SelectedResponseHandler(this, new SelectedResponseEventArgs(response));
    19. }
    In your case, you said you don't want to actually report the response selection back to the Dialogue System until the player confirms. To do this, you might modify the script something like this:

    Code (csharp):
    1. public Button buttons; // Assign your buttons here.
    2.  
    3. private Response[] currentResponses; // Remember the current responses.
    4. private Response currentResponse; // Remember the most recently clicked response.
    5.  
    6. public void ShowResponses(Subtitle subtitle, Response[] responses, float timeout) {
    7.     // Set up the response menu:
    8.     for (int i = 0; i < buttons.Length; i++) {
    9.         var useThisButton = (i < responses.Length);
    10.         buttons[i].gameObject.SetActive(useThisButton);
    11.         if (useThisButton) buttons[i].GetComponent<Text>().text = responses[i].formattedText.text;
    12.     }
    13.     currentResponses = responses;
    14.     currentResponse = null;
    15. }
    16.  
    17. public void ClickedResponseButton(int buttonIndex) {
    18.     // When the player clicks a response button, just record the response:
    19.     currentResponse = currentResponses[buttonIndex];
    20. }
    21.  
    22. public void ClickedConfirmResponseSelection() {
    23.    // When the player toggles out to confirm the selection, send it to the Dialogue System:
    24.     if (currentResponse != null) {
    25.         SelectedResponseHandler(this, new SelectedResponseEventArgs(currentResponse));
    26.     }
    27. }
     
  22. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Hi, how would you use the continue buttons for some conversations and not for others? I am using the Unity GUI.

    Thankyou,

    Lee
     
  23. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @LeeAllen - Here are a few ways. They work for all GUI systems.

    1. In your conversation's START node, use the SetContinueMode() sequencer command:

    SetContinueMode(false)

    2. Add an Override Display Settings component to your conversants, and set the Continue Button mode. If that's the only difference, set up the rest of the Override Display Settings values to be the same as the Dialogue Manager's Display Settings.

    3. In a script on the Dialogue Manager, actor, or conversant (such as in an OnConversationStart method), set DialogueManager.DisplaySettings.subtitleSettings.continueButton.
     
  24. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Perfect! Thank you once again for your incredibly quick responses!!! Not just one but 3 solutions!!!
     
  25. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    Well, after some tinkering, I have results in my 2D prototype! The toggle-based response menu and scrolling instantiated subtitles are working fine.



    Though, I've found that, firstly, turning on player character subtitles breaks the conversation (PC subtitles instead spawn as the default template and don't continue the convo), I really can't think of a way to implement non-verbal options or slow down the timer (don't know if said timer is affected by timescale), and there's no way to remove the delay between showing a subtitle and changing the response menu.

    Also, one problem that's less specific to this is that the character name isn't displaying properly for some reason. Not sure why that is, it's the same with the regular UI templates.
     
  26. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Hi again... Sorry to bother you so much!

    When I use the Dialog Manager with 'Do not destroy on load' and have the dropdown for continue button on any setting other than Never it will reset to 'Never' upon loading the next scene. I have tested this with a clean scene. Is there an easy way to force it to remember my setting when it moves from scene to scene?

    Thanks again!
     
  27. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Candescence - I'm not sure exactly what you mean about the PC subtitles spawning as the default template. Here's some info that might help:

    The Dialogue System passes a Subtitle to your dialogue UI script's ShowSubtitle() and HideSubtitle() methods. This object has a speakerInfo property that has a lot of info about who's speaking the current line. You can check speakerInfo.characterType if you want to handle PC subtitles differently from NPC subtitles.

    It may be that the PC subtitle is just playing its Sequence. (See below for relevant info about sequences.) After a few seconds (depending on the text length), does it progress to the next stage in the conversation?

    What do you mean by non-verbal options? RPGs often put "actions" in brackets and italics, like:
    • Thug: Gimme your wallet!
      • Do you know who I am?!
      • Please don't hurt me!
      • [punch the thug]
    To do this in the Dialogue System, wrap your Dialogue Text in emphasis tags, like this:

    Dialogue Text: [em1] [punch the thug] [/em1]​

    You can define the appearance of [em1] through [em4] on the Dialogue Editor's Database tab.

    If you mean making something happen in the game, use the Sequence field. (See Sequences.) For example:

    Sequence: AnimatorPlayWait(Punch)

    Sequences are specified using text commands like AnimatorPlayWait(). This makes it easy for authors to write sequences while they're writing dialogue, and it works best with third party editors like Chat Mapper and articy:draft.

    If you prefer to design your sequences using an interactive scrubbing editor such as uSequencer or Cinema Director, you can do that, too. See the Third Party Support section for tips on using these tools.

    By default, the timer is not affected by timeScale. This allows you to pause the game using Time.timeScale=0 and still run conversations. If you want the Dialogue System to be affected by Time.timeScale, set DialogueTime.Mode to Gameplay:
    Code (csharp):
    1. DialogueTime.Mode = DialogueTime.TimeMode.Gameplay;
    Unless you've set a dialogue entry's Sequence field, the dialogue entry will use the Default Sequence defined on the Dialogue Manager. This is initially set to:

    Delay({{end}})

    which delays for a duration based on the text length. If you want to immediately move on to the response menu, change it to:

    None()
    (You can also set this through the dropdown in the Dialogue Manager Setup Wizard.)

    It looks like the conversation is using the Dialogue Manager GameObject as the actor or conversant. I'm not sure how you're starting the conversation, but try to assign GameObjects representing the participants. For example, if you're using a Conversation Trigger, you can assign the GameObjects to the Actor and Conversant fields. The Actor is usually the player, and the Conversant is the NPC. They can be empty GameObjects if you're only using them for this purpose. The dialogue UI will use the name of the GameObjects. If you want to use a different name, add an Override Actor Name component to the GameObjects.

    If you temporarily set the Dialogue Manager's Debug Level to Info, it will log (among many other things) the actor and conversant when starting conversations. You can use this to see what GameObjects the conversation is using for them.

    Hi @LeeAllen - Sounds like another Dialogue Manager is in the scene. In the first scene that has a Dialogue Manager, rename it something like "Master Dialogue Manager". Then tick Allow Only One Instance on all of your Dialogue Managers.

    When you change scenes, is there more than one Dialogue Manager? If there's only one, it is the one named "Master Dialogue Manager"?

    If that doesn't help, please feel free to send an example project to tony (at) pixelcrushers.com. If it's too big for email and you can't provide a download link, let me know and I'll send you FTP upload instructions.
     
  28. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    Okay, so I got the timescale and actor name stuff fixed, but...

    Nope. I mean the subtitle is just set to the default text, unchanged, and the conversation doesn't proceed at all. The script doesn't distinguish between subtitle types.

    Well, I'm implementing a separate 'interaction menu' ala classic adventure games, and I'm hoping to integrate certain actions in it on a contextual basis (and when certain conditions are met, such as a player being close enough to the other actor in the conversation). Sure, I could do it in the response menu, but I want to keep verbal responses and non-verbal responses separate.
     
  29. TopThreat

    TopThreat

    Joined:
    Aug 7, 2012
    Posts:
    136
    Hi Toni, I followed the instructions and changed the name of the dialog manager and then moved to the next scene. It did the same thing again (And there was not another dialog manager that I could find. All other settings remained as well besides the Continue button dropdown. I need to get a few quick changes released on my project and then I will see if I can put together a scene using the demo assets to see if it's duplicated.
     
  30. iScream8

    iScream8

    Joined:
    Feb 16, 2015
    Posts:
    10
    Hi, I'm having a problem playing a bark during conversation. I can't make it to work. I already ticked the option "allow during conversation" on my bark trigger and/or my barkOnIdle but no luck... Can you include some example for that? I'm making a storytelling with an interactive dialogues so there's a narration and barks in my scene. When the narration starts to play the barks will stop. In 5 scenes I only have 1 dialogue manager.
     
  31. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Would it be possible for you to send me your dialogue UI script?

    In the meantime, here are some things that might help you identify the issue:
    • Set the Dialogue Manager's Debug Level to Info. The Console might give you some insight into the current state of the conversation.
    • While playing, open the Dialogue Editor to the Conversations tab and select the conversation. As the conversation plays, the current dialogue entry node will be green. Its links will be green when their Conditions are true and red when they're false:
    You could go a lot of ways with this. Here's one idea:

    Set up your interaction menu as UI buttons. Name the GameObjects according to their action (e.g., "Attack", "Hug, "Take", etc.).

    Add a custom field named "Action" to the Dialogue Entry template. When you're writing your conversation, set the Action field of your player response nodes. If it's a regular dialogue response, set Action to a blank string. If it's a nonverbal action, set it to the name of the corresponding action UI button (e.g., "Attack", "Hug", etc.). If you want to get fancy, you could define it as a Custom Field Type and give it a dropdown menu.

    In your ShowResponses method, first set all of the nonverbal UI buttons non-interactable. As you loop through the responses, if the Action field is blank, add the response to the response menu. Otherwise, use the Action field's value to enable the corresponding UI button. For example:
    Code (csharp):
    1. // Add this script to each nonverbal action button:
    2. public class ActionButton : MonoBehaviour {
    3.     public int responseIndex { get; set; }
    4. }
    5.  
    6. ... // (Put the code below in your dialogue UI script:)
    7.  
    8. public ActionButton[] actions; //<-- Assign your action buttons in inspector.
    9.  
    10. public void ShowResponses(Subtitle subtitle, Response[] responses, float timeout) {
    11.     // Disable all nonverbal action buttons:
    12.     for (int i = 0; i < actions.Length; i++) {
    13.         actions[i].GetComponent<Button>().interactable = false;
    14.     }
    15.  
    16.     // Clear the response menu:
    17.     int buttonIndex = 0;
    18.     for (int i = 0; i < buttons.Length; i++) {
    19.         buttons[i].gameObject.SetActive(false);
    20.     }
    21.  
    22.     // Set up the responses:
    23.     for (int i = 0; i < responses.Length; i++) {
    24.         string action = Field.LookupValue(responses[i].destinationEntry.fields, "Action");
    25.         if (string.IsNullOrEmpty(action)) {
    26.             // Regular dialogue response. Add to response menu:
    27.             buttons[buttonIndex].gameObject.SetActive(true);
    28.             buttons[buttonIndex].GetComponent<Text>().text = responses[i].formattedText.text;
    29.             buttonIndex++;
    30.         } else {
    31.             // Nonverbal action. Enable its button using its GameObject name:
    32.             for (int x = 0; x < actions.Length; x++) {
    33.                 if (string.Equals(actions[x].name, action)) {
    34.                    actions[x].GetComponent<Button>().interactable = true;
    35.                    actions[x].responseIndex = i;
    36.                    break;
    37.                 }
    38.             }
    39.         }
    40.     }
    41.     currentResponses = responses;
    42.     currentResponse = null;
    43. }
    That code is hardly an example of flawless coding practice, but I hope it gets the idea across.

    I used an "ActionButton" script on the action buttons to allow them to remember what response they correspond to. When clicked, they could call the dialogue UI script's ClickedResponseButton(responseIndex) method to move the conversation forward. If you want actions to stop the conversation instead, you could omit all this extra stuff and just call DialogueManager.StopConversation().

    Thanks! I can't replicate the issue. If you can, please send me replication steps or export the scenes as a unitypackage and let me know which version of Unity you're using.

    This one I can confirm. It's already fixed in the maintenance release coming out tomorrow.
     
  32. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    The support in this forum is beyond anything I have seen IN or OUTSIDE the asset store. Thank you.
     
    hopeful, Tinjaw and TonyLi like this.
  33. RodzGames

    RodzGames

    Joined:
    Dec 9, 2014
    Posts:
    24
    Hello, I need help with the Sequencer. I try to do simple things like setting a trigger (Animator) but it doesn't work.

    To start the conversation, I call "DialogueManager.StartConversation(conversation, transform);"
    (The "transform" is from the NPC, he's the only speaker)
    On a dialogue entry, I use AnimatorTrigger("TestTrigger")
    When I test it, the console says "No Animator found on "
    But I clearly have an Animator on the NPC.

    What am I missing? I read the documentation but I still don't understand...

    Thanks.
     
  34. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Matrix456 - Thanks for using the Dialogue System for Unity! Try:
    Code (csharp):
    1. DialogueManager.StartConversation(conversation, transform, transform);
    When you omit the conversant's transform, it's assigned null. It's possible that your dialogue entries are set up so they alternate actor - conversant - actor - conversant - etc. for the speaker. So the speaker's transform is null for half of the lines. When you omit the subject from a sequencer command, it uses the speaker's transform.

    If that doesn't help, temporarily set the Dialogue Manager's Debug Level to Info. This will give you more information about the current speaker of each dialogue entry, and it will report what transform it found for the AnimatorTrigger command's default subject.

    If that doesn't help, please feel free to send an example project to tony (at) pixelcrushers.com. I'll be happy to take a look!
     
  35. RodzGames

    RodzGames

    Joined:
    Dec 9, 2014
    Posts:
    24
    Thanks, I found the problem. I didn't correctly set the actors name.

    I have another question.

    I try to use the Override Actor Name Component. I give that to the NPC, I set the Override Name field, but it doesn't replace the name in the conversation. I have no idea what I'm doing wrong.
     
  36. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Matrix456 - It should replace the name used in the Portrait Name, but it won't replace the name in the conversation's Dialogue Text. To replace the name in the Dialogue Text, use [var=Conversant]:

    Dialogue Text: Greetings, player! My name is [var=Conversant]!​

    If the Override Actor Name component isn't replacing the Portrait Name, then the conversation is probably using the wrong GameObject. If you set the Dialogue Manager's Debug Level to Info and start the conversation, you'll see a line in the Console like this:

    Dialogue System: Starting conversation 'title', actor=yourActor, conversant=yourConversant.​

    where yourActor is the transform of the actor and yourConversant is the transform of the conversant. The conversation will look for Override Actor Name components on these.

    I don't know if this extra info is relevant to your situation: You can involve any number of characters in a conversation. If a dialogue entry's speaker is not the main actor or conversant, the Dialogue System will look for a GameObject matching the speaker's name. It will then look for an Override Actor Name on this GameObject.
     
  37. RodzGames

    RodzGames

    Joined:
    Dec 9, 2014
    Posts:
    24
    I didn't find the problem yet. It still doesn't replace the Portrait Name.

    I think the conversation find the correct GameObject. When I set the Debug Level to Info, the console says :
    Variable["Actor"] = "NewName"

    "NewName" is the name I want to see in the Portrait Name. But it still show "NPC".

    I'll keep searching.
     
  38. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Is "NPC" the name of the GameObject?

    Usually the player is the Actor, and the NPC is the Conversant. You should also see something like this in the Console:

    Variable["Conversant"] = "SomeName"​

    It might help to play through the Feature Demo scene with Debug Level set to Info. When you talk to Private Hart, you'll see that the actor is Player and the conversant is Private Hart. As each line plays, you'll see the character who is saying that line:

    Dialogue System: Starting conversation 'Private Hart', actor=Player (UnityEngine.Transform), conversant=Private Hart (UnityEngine.Transform).
    ...
    Dialogue System: Private Hart says 'Lieutenant! We have a problem, sir!
     
  39. RodzGames

    RodzGames

    Joined:
    Dec 9, 2014
    Posts:
    24
    Yes, NPC is the name of the GameObject (I'm just testing).

    Wait, I don't understand. The actor is supposed to be the player? I thought the Actor was the one talking... ? And the Portrait Name always show the Actor Name... right?

    I set the NPC as the Actor in every dialogue entry. Is it a problem?

    I checked the Feature Demo, but there's no Override Actor Name Component, so I can't compare.

    I'll keep searching. Thanks you for taking the time to help me. I really appreciate it.
     
  40. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Happy to help! Especially when it comes to some confusing terminology. The Dialogue System data model is based on Chat Mapper, which is a commercial dialogue editor used by a lot of professionals. It's a great model, but it has one bit of really confusing terminology:

    When you create a dialogue database, you define actors on the Actors tab such as the Player and all your NPCs.

    When you define a conversation, you specify an Actor and a Conversant. The conversation's Actor is the primary participant, usually the player. The conversation's Conversant is the other participant, usually the NPC. This is the first confusing bit. Both participants are "actors" on the Actors tab. But in the conversation, one is the conversation's Actor and the other is the conversation's Conversant.

    When you run this code:
    Code (csharp):
    1. DialogueManager.StartConversation("Title", myPlayer, myNPC);
    it records myPlayer as the conversation's Actor transform and myNPC as the conversation's Conversant transform.


    To make it even more confusing, every dialogue entry node has an Actor and a Conversant. In a dialogue entry, the dialogue entry's Actor is the one who's speaking, and the dialogue entry's Conversant is the one being spoken to.

    (To try to reduce ambiguity, in the Dialogue System's sequencer commands the keyword speaker refers to the one who's speaking the current dialogue entry, and listener refers to the one being spoken to.)

    Anyway, getting back to portrait names.... When the Dialogue System plays a dialogue entry, it looks at the dialogue entry's Actor:
    • If it's the same as the conversation's Actor, it uses the conversation's Actor transform (e.g., myPlayer).
    • If it's the same as the conversation's Conversant, it uses the conversation's Conversant transform (e.g., myNPC).
    • Otherwise it looks for a GameObject whose name matches the speaker's name in the dialogue database, and it uses that transform.
    Once it has a transform, it checks for an Override Actor Name component on that transform. (This is all cached for efficiency.)

    Also, the actor's definition in the Dialogue Editor's Actors tab has a Boolean field named "IsPlayer". If this field is True, it displays the text through the dialogue UI's PC Subtitle elements. Otherwise it plays it through the NPC Subtitle elements.


    Sorry about steering you wrong on the Feature Demo. I forgot it didn't have Override Actor Names. However, you can add an Override Actor Name to Private Hart. If you set the Override Name to "Bob", then when Private Hart speaks his Portrait Name will be "Bob".
     
    hopeful likes this.
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    The Dialogue System for Unity 1.5.7 is now available for download on the Pixel Crushers customer download site! (PM me your Asset Store invoice number if you need access.) It should be on the Asset Store in a few days!

    This is primarily an interim maintenance release, not the next big feature release with quest groups.

    Core
    • Dialogue Editor improvements:
      • Can now reorder items, actors, locations, variables, and conversations.
      • Copy Conversation now keeps original node positions in copy; if creating multiple copies, numbers them 1,2,3,etc.
    • Changed: Conversations also check actor (not just conversant) for dialogue UI/setting overrides.
    • Improved: Selector now only registers button/mouse up if selecting same object as when clicked down.
    • Improved: Sequencer now warns if it's creating a temp MainCamera.
    • Fixed: If Dialogue Manager is configured to preload resources, gracefully handles errors in preloading.
    • Fixed: Bark On Idle didn't respect Allow During Conversations checkbox.
    • Fixed: PC/NPC/Dialogue Manager wizards weren't always setting saving all changes.
    • CSV Import: Fixed bug where some dialogue entry fields were duplicated.
    • Unity UI support:
      • Added: Script-free support for world space dialogue UIs (e.g., speech bubbles).
      • Improved: Can now queue alerts.
      • Fixed: Subtitles only trigger typewriter effect if script is enabled.

    Third Party Support
    • articy:draft Converter improvements:
    • Added Starter template project.
    • Review button now uses custom fields to identify entity types.
    • Supports quest state dropdowns.
    • Splits dialogue fragments on pipes.
    • If dialogue fragment has Script field, it's imported as dialogue entry's Script.
    • Link order is now determined by position as in articy:draft's Presentation Mode.
    • Improved searching for portrait images.
    • Chat Mapper: Added quest entries to starter template.
    • Inventory Pro: Support added (maintained by Inventory Pro developer).
    • PlayMaker: Added OnConversationResponseMenu event.
    • RPG Kit: Updated integration to support RPG Kit 3.1.
    • Third Person Controller: Updated (maintained by Opsive).
    • UFPS: Fixed cursor hiding in UFPS 1.5.0+.
     
    hopeful likes this.
  42. RodzGames

    RodzGames

    Joined:
    Dec 9, 2014
    Posts:
    24
    Thanks for the explanation.

    I added an Override Actor Name Component on Private Hart, I set the Override Name to Bob, but it still doesn't replace the name.

    I took a screenshot if that can help find the problem.



    Did I do something wrong?
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    @Matrix456 - Are you talking about the "Private Hart" text that's floating above the NPC's head in the screenshot? That's just a GUIText nameplate that I added to the NPC. It's not connected to the Dialogue System.

    Override Actor Name affects the NPC Portrait Name in the dialogue UI, such as the "Private Hart" shown here:



    If it's not affecting the NPC Portrait Name in your scene, make sure your dialogue UI's NPC Subtitle > Portrait Name field is pointing to the correct text element.

    You can also make Override Actor Name affect that GUIText nameplate if you want. You'd just need to add a little script like this to the main NPC GameObject and assign the nameplate GUIText:
    Code (csharp):
    1. public class Nameplate : MonoBehaviour {
    2.     public GUIText nameplateText; //<-- Assign this.
    3.  
    4.     void Start() {
    5.         nameplateText.text = OverrideActorName.GetActorName(this.transform);
    6.     }
    7. }
    OverrideActorName.GetActorName() is a static function that gets the actor name for any GameObject. If the GameObject has an Override Actor Name component, it returns the component's value; otherwise it returns the GameObject's name.
     
  44. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    393
    Hi,

    I have just purchased, things look ok but I'm currently feeling like I'm fighting the system, perhaps I'm missing something that would make my job easier?

    I'm trying to create a dialogue system where the PC response is triggered by a timer - similar to something like The Walking Dead or Alpha Protocol. The player's input (GamePad only) is always 1 of 4 responses. The player is free to switch and change their mind before the timer runs out.

    The 4 different inputs refer to different general approaches to the conversation so I would like particular response nodes tied directly to a specific button. I can't work out how to do this? How to make a particular Conversation node tie directly to a specific Response node? It looks like its always tied to how many nodes there are and thus shifts around? Also, I can't seem to change the color of the Response label, it's set to white in every field I can see that would affect the color but continues to be black.

    Also how can I get the timer to fire the chosen selection? It only looks like I have two options from the Timer enum, 'Chose First Response' & 'End Conversation'. I would also like to be able set which of the 4 options should be the default per that response.

    Would there also be a way to display the response options before the question has finished (specifying the time) so when the timer ends it is a natural place for that particular response ?

    Hope that makes sense?

    Thanks
     
  45. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    393
    Sorry lots of questions but it looks like the system wasn't built for my particular use case and feeling a little disheartened - I hope I'm wrong!?
     
  46. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @silentslack - You can do this with the Dialogue System. This is actually one of its strong design points. It handles user interfaces modularly. You can swap functionality in and out, and the rest of the system (cutscene sequences, internal data, branching logic, etc.) will work happily with it.

    In just a bit, I'll reply in more detail with a description of how to do what you're asking.
     
    hopeful likes this.
  47. Candescence

    Candescence

    Joined:
    Aug 26, 2014
    Posts:
    107
    Thanks for the help with the non-verbal actions, pretty straightforward.

    Well, I've tried looking at the debug info, but when PC subtitles are on, the conversation literally doesn't advance, none of the nodes turn green. If the option is turned on in the middle of a conversation, the conversation still doesn't advance.

    Here's the code for the subtitles:

    Code (CSharp):
    1. public void ShowSubtitle(Subtitle subtitle) {
    2.         // Add your code here to show a subtitle. Subtitles contain information such as the player
    3.         // type (PC or NPC), portrait texture, and the formatted text of the line.
    4.      
    5.         GameObject copy = Instantiate(subtitleTemplate);
    6.  
    7.         copy.transform.SetParent(subtitlePanelContent);
    8.         Image portrait = copy.transform.FindChild("Portrait Image").GetComponent<Image>();
    9.         Sprite tempSprite = Sprite.Create(subtitle.GetSpeakerPortrait(), new Rect(0f,0f, subtitle.GetSpeakerPortrait().width, subtitle.GetSpeakerPortrait().height), Vector2.zero);
    10.         portrait.sprite = tempSprite;
    11.         Text actorName = copy.transform.FindChild("Portrait Name").GetComponent<Text>();
    12.         actorName.text = subtitle.speakerInfo.Name;
    13.         Image divider = copy.transform.FindChild("Divider").GetComponent<Image>();
    14.         Text subtitleLine = copy.transform.FindChild("Subtitle Line").GetComponent<Text>();
    15.         subtitleLine.text = subtitle.formattedText.text;
    16.  
    17.         subtitleScroll.verticalNormalizedPosition = 0f;
    18.     }
    That's literally all there is to it. It's basically a subtitle type-agnostic function. Or, well, it should be.

    Also, can't get the scroll part of the subtitle area to immediately go to the bottom upon instantiation, which is weird.
     
  48. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Let's take The Walking Dead as an example:



    There are 4 response button positions corresponding to A, B, X, & Y. (There's also a timer. I'll address that further down.)

    An equivalent in the Dialogue System is the Wheel2 UI prefab:



    This UI has 6 explicitly-defined response button positions. If you look at the prefab, you'll see that the buttons are assigned to the Buttons list, not to the Button Template and Button Template Holder that are outlined in the screenshot below:


    (^ Don't assign explicitly-positioned buttons to the Button Template fields. They're only for auto-placed responses.)

    For Wheel2, the response buttons assigned to the Buttons list are numbered 0, 1, 2, 3, 4, and 5.

    When you define a response dialogue entry, you can specify its button position by using the [position #] Markup Tag in its Menu Text. For example, let's say you've reserved position 0 for "nice" responses and position 5 for "mean" responses. Then you could set up your responses like this:
    • [NPC] Dialogue Text: Hey, buddy, can you spare a dollar?
      • Menu Text: [position 0] Poor guy, here's a twenty!
      • Menu Text: What do you need it for?
      • Menu Text: Can I ask you a question first?
      • Menu Text: [position 6] Outta my way, bum, or I'll kick you!
    The "Poor guy" response will go into the first button. The "Outta my way" response will go into the last button. The remainder, since they don't have [position #] tags, will go wherever they fit, according to the Button Alignment dropdown.

    Use emphasis tags (aka "em tags"). First, open your dialogue database in the Dialogue Editor. Go to the Database tab, and expand the Emphasis Settings section. Set the appearance for emphasis settings 1 - 4. Let's say you set emphasis 1 to blue, and emphasis 2 to red.

    Then wrap your text in [em#] markup tags:
    • [NPC] Dialogue Text: Hey, buddy, can you spare a dollar?
      • Menu Text: [position 0] [em1]Poor guy, here's a twenty![/em1]
      • Menu Text: What do you need it for?
      • Menu Text: Can I ask you a question first?
      • Menu Text: [position 6] [em2]Outta my way, bum, or I'll kick you![/em2]
    I colored the tags above just to help them stand out here. In the response menu, "Poor guy..." will be blue, and "Outta my way..." will be red. (If it's coloring the button's background texture instead of the text, check the Unity UI Response Button components on your response buttons.)

    This is something where you'll want to swap in a new, slightly different behavior with a small script. I'll send you an script that does this later today. (I'm out of the office at the moment.)

    Yes. You can set something to run (a typewriter effect, a voiceover or animation, etc.) and leave it running while moving on to the next stage in the conversation. You can also play an additional sequence during the response menu. There are necessarily some nuances to be able to support all the different things different developers want to do, but here's a simple example:
    • [NPC] Dialogue Text: Hey, buddy, can you spare a dollar?
      Sequence: Audio(hey_buddy_voiceover); AnimatorTrigger(PuppyDogEyes)
      Response Menu Sequence: Audio(cough)@2; AnimatorTrigger(ExtendCup)@3
      • Menu Text: [position 0] [em1]Poor guy, here's a twenty![/em1]
      • Menu Text: What do you need it for?
      • Menu Text: Can I ask you a question first?
      • Menu Text: [position 6] [em2]Outta my way, bum, or I'll kick you![/em2]
    As soon as the NPC says "Hey, buddy...", it will play the audio clip hey_buddy_voiceover and trigger the animation PuppyDogEyes.

    Then it will go to the response menu. At the 2-second mark (if the response menu is still up), it will play the audio clip cough. At the 3-second mark, it will trigger the animation ExtendCup.
     
  49. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Candescence - I wonder if maybe it's waiting for a continue button. On your Dialogue Manager, what is Subtitle Settings > Continue Button set to?

    If it's set to Never, this rules out continue button issues. If this is the case, can you temporarily set Debug Level to Info, reproduce the issue, and email the editor.log file to tony (at) pixelcrushers.com? Please let me know the text of the player subtitle that it got stuck on.

    Unity UI needs a frame to recompute the layout before you adjust the scrollbar. You'll have to set the position after one frame. Instead of this:
    Code (csharp):
    1.     subtitleScroll.verticalNormalizedPosition = 0f;
    2. }
    try this:
    Code (csharp):
    1.    StartCoroutine(ScrollToBottom());
    2. }
    3.  
    4. IEnumerator ScrollToBottom() {
    5.     yield return null; // Wait 1 frame.
    6.     subtitleScroll.verticalNormalizedPosition = 0f;
    7. }
     
    hopeful likes this.
  50. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    393
    @TonyLi dude that is an astonishing reply! I have just quickly skim read but some great extra pointers that I hope will solve my issues - thanks! I will report back!