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. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Hi @MaFoShi - I have attached an example scene to this email. It has two buttons: English and Chinese. If you click Chinese, it should show the dialogue like this:

    upload_2019-1-9_8-42-6.png

    Have you set the language using one of the methods described here?

    For example the Chinese button sets the language using the SetLanguage() method and starts the conversation:

    upload_2019-1-9_8-40-55.png

    In your database, make sure your localized field doesn't have any accidental blank spaces:

    upload_2019-1-9_8-44-18.png

    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.
     

    Attached Files:

  2. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    30
    Hi TonyLi, your example works correctly and I rechecked the Display Name Fields, there are not blank space there.
    I have debugged the code and found in the GetTableField method of DialogueLua.cs, at line 816, your example returns a LuaTable, but in my case, this returns a null value, I wondered where the table it is? this should be the problem.
     
  3. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    30
  4. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    The only way I have been able to reproduce this problem is with these steps:

    1. Create a GameObject.
    2. Add a Dialogue Actor component to the GameObject. Leave the actor dropdown unselected, or manually set the actor name to "Old Man.
    3. Assign this GameObject to the Dialogue System Trigger's Start Conversation > Conversation Actor or Conversation Conversant.
    If that is the problem in your scene, select "Npc" in the actor dropdown to associate the GameObject with the "Npc" actor.

    Can you please send an example project to tony (at) pixelcrushers.com? You can zip up the Assets and ProjectSettings folders. You don't need to include the other folders.
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    I'm finishing work for the day, but I'll check back first thing in the morning. If my previous reply doesn't provide a solution, please send me an example project if possible. Thanks!
     
  6. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    30
    I guessed there must be something wrong with cache or similar thing in Dialogue System.
    so I have recreated my project and reimported all stuff, finally, the Display Name worked for me.
     
    Last edited: Jan 10, 2019
  7. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    30
    I suddenly thought that this must be something wrong about the new nested prefab system of Unity 2018.3, because I have found some other data of prefabs can't save correctly either.
     
  8. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    I'm glad you got it working. If you ever reproduce the issue, please send me a copy of the project if possible.

    The dialogue database is a ScriptableObject asset. It's not a prefab, so it shouldn't be affected by any issues with the new prefab system. The Dialogue System does have prefabs, such as the Dialogue Manager prefab and the dialogue UI prefabs, but that wouldn't affect localization. In the Dialogue System, localization only happens in code and the ScriptableObject assets. Make sure you're using the latest version of 2018.3. The beta versions especially had several prefab-related bugs.
     
  9. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Is it possible to have a text log system. a Dialog log system. Im trying to have a text message system where you can view old messages in the conversation.


    Something like this.
     
  10. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Yes. See the Runic UI prefab for an example. It maintains a scrollback of the conversation, similar to how a lot of western RPGs work.

    For a fuller framework, import the Textline template and Menu Framework from the Dialogue System Extras page. It works similarly to Three Minute Games' Lifeline series, which plays out like a simulated text message system.
     
  11. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Holy S***!! I've been struggling to do this for a while now. I was able to make one with Playmaker and arrays but that was so looong!!

    Thanks for this.

    Would I be able to control the scrolling and option selection with keys? Also how would I go about accessing the message log that we have already seen??
     
    Last edited: Jan 12, 2019
  12. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Yes to option selection. Set the Dialogue Manager's Input Device Manager > Device to Keyboard, and/or tick Always Auto Focus. This will ensure that an option on the response menu is always focused so you can navigate among them.

    Scrolling uses Unity UI's ScrollRect, which doesn't have any built-in functionality for scrolling with keys. But it scrolls with swipes and a scrollbar if you want to add one. You can always add a custom script to scroll with keys, but you'd have to write it or find one open source or on the Asset Store.
     
  13. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    I do not know if the thing has already been asked, but the thread is really long!
    Is there a bool telling me if a dialogue is running?
    I need to display / hide the cursor based on a bool (the asset option does not work because of other code that hides it)

    Code (CSharp):
    1.         public void MouseCursorUpdate()
    2.         {
    3.             //Show cursor cases
    4.         cursorShow = showCursor || InShipCamera.instance.freeLookActive ||KalebGUI.instance.vendorGUIOpen || KalebGUI.instance.kalebSettingsGUIOpen || mapIsOpen;
    5. //I need to add: || DialogueManager.aDialogueisActive;
    6.          
    7.  
    8.             if (cursorShow)
    9.             {
    10.                 Cursor.lockState = CursorLockMode.None;
    11.                 Cursor.visible = true;
    12.              
    13.             }
    14.             else if (!cursorShow)
    15.             {
    16.                 Cursor.lockState = CursorLockMode.Locked;
    17.                 Cursor.visible = false;
    18.             }
    19.         }

    EDIT:
    I found:
    DialogueManager.instance.IsConversationActive;
    Resolved ;)
     
    Last edited: Jan 12, 2019
    hopeful and TonyLi like this.
  14. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    You can also just check DialogueManager.isConversationActive. It's the same thing but a little shorter.
     
  15. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Alright thanks. 1 more question, how would I go about viewing the message log. Like I want a button to open the messages and another button to close it.
     
  16. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    Another question. Sorry form my bad english.

    When an actor utters a certain phrase I would like to execute a certain method on my script placed on a scene object.
    But On Execute only accept prefabs !? :eek:

     
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    The Textline template's dialogue UI does this. You can switch back and forth between conversations, and it saves the log of each one. If you don't want to use Textline, you can write a simple script like the ConversationLogger.cs script to log the messages.

    Dialogue databases exist outside of scenes, so they can't reference scene objects. (At least not without messy, extra complexity.) You can assign a prefab or ScriptableObject instance, or you can register your method with Lua. This is the typical way to do it. Then you can use that method in the dialogue entry's Conditions and/or Script fields.
     
  18. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Im confused. I'm a new scene and carried he dialogue database from Textline to the new scene. I create a button and can advance the text till the end. When it ends, the menu goes away.

    My question, when i press the button to open it up again, the conversation doesn't save. I have to advance the convo all over again.

    I know using the example scenes it saves but I want it in a brand new scene.




    In order to explain more about what i mean. Im not making a text game. It's a 3rd person game where you can pull up a phone and enter a text message menu which will contain the text messages.

    I know it saves for the example, but this is different.
     
    Last edited: Jan 13, 2019
  19. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    I'll put together an example and post it here later today.
     
  20. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Ooh Thank you very much.
     
  21. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    Thanks for the reply. ;)
    I do not know what Lua is, I'll try to document myself.
    I hope there are some sample scripts to do what I need.
    I think it's a basic thing for this type of asset.

    EDIT:
    Great, it works. :D
    Thank you!
     
    Last edited: Jan 13, 2019
  22. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    I've attached a simple example to this post. It uses a tiny script to open and close the SMS conversation. We can treat it as a starting point if your design calls for something different. It uses the Textline dialogue UI, so it assumes you've imported Textline.


    Glad to help!

    [EDIT: Newer version here.]
     
    Last edited: Jan 14, 2019
  23. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Thank you that's definitely what I need. I just need to know a couple more things. How would I go about adding a message notification thing. Like when a new messages comes up, i can put a graphic on the screen. I can use variables for this right?

    I have another general question, SO let's say on day 1 I get like 7 messages and thats it. Day 2 I get like 4 messages and so on. How do I go about doing that?

    I have an idea about how i think i can do it. I write all messages and then check for a variable to see if day 2 variable is active and then it will display the messages?

    Is it also possible to do the Lobby room thing mentioned in the textline document for this? I want messages from more than 1 person. The lobby room example you posted on your forum doesnt work anymore.

    I duplicated the sms device and changed the button press to a new key and added a new conversation and while i started the conversation, it didn't work properly. It only saved that 1 conversation, the first one i pressed.
     
    Last edited: Jan 14, 2019
  24. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    You can use alerts to notify the player. Configure a Dialogue System Trigger with a Show Alert action, or call DialogueManager.ShowAlert() in code, or use the equivalent visual scripting action.

    Yes. Add these as conditions to your dialogue entries. As long as the conditions are true, it will keep going through the dialogue entries adding messages.

    Use the same TextlineDialogueUI. Make sure the Use Conversation Variable checkbox is ticked. In the Dialogue Editor, add a variable named "Conversation". Set up different GameObjects with Dialogue System Triggers, one per conversation. Add two actions: Run Lua Code and Start Conversation. In Run Lua Code, set the Conversation variable to the title of the conversation. In Start Conversation, select the conversation.
     
  25. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    @namdo - Here's an improved version of the SMS TPC example. It has a menu from which you can choose SMS conversations, and saving/loading games works better. I also added a _README documenting the steps used to set it up.

    EDIT: See post below for updated example.
     
    Last edited: Jan 15, 2019
  26. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    I was literally to post. Thanks for the update. Also thanks for taking the time to help.

    While it does work, there are still some issues with the saving though. For example,

    When i finish 1 conversation and it ends. If go back to the same conversation, it starts all over again. Now when i start that conversation and press the x button to exit the conversation, if i go back to that conversation, it will show the same conversation over and over again like in the pic.


    When i play 1 conversation to the end, if i go back to that conversation it starts all over again. It only saves if i press the x button and go back before the conversation finishes.

    In fact there are also times when you see conversation 1 in conversation 2. Only happens if you do it the way i said in the bolded above.
     

    Attached Files:

    • AA.PNG
      AA.PNG
      File size:
      344.7 KB
      Views:
      132
  27. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    What do you want to happen when you reach the end?

    I think a common way to handle SMS-style conversations is to loop the last entry so the conversation doesn't end:

    upload_2019-1-14_14-41-53.png

    For variety, you can add random variations, but that's the general principle.
     
  28. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158
    Ok. After I finish a conversation and it goes back to the gameplay screen, it i go back to that conversation, it starts again from the top. It doesn't show that we've had this conversation before. Like replaying the convo over again. Do i use a variable to make the conversation stay there.

    When i finish convo on day 1, if go back to the convo like to read it, i dont want to have to go through it again. We've been through it once already.

    Also like i mentioned earlier, it seems to duplicate convos. IF i finish 1 convo to the end and go back to the gameplay screen. if i go back to the convo and maybe press the x button to quit to the gameplay. if i go back to that same convo, it will duplicate the convo. if you check the pic i posted, you'll see what i mean.
     
  29. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Are you using the newer example that I posted?

    If so, on the TextlineDialogueUI component, did you tick the Use Conversation Variable checkbox? This allows the TextlineDialogueUI to track multiple conversations.

    Let's figure out a good way to handle this in your case. Let's say you get through day 1. At the end, either the NPC or the player could say something like "Talk to you tomorrow," and then the conversation could automatically close for now. When you resume the conversation on day 2, it could pick up from there by adding day 2's messages. Is that how you'd want it to work?
     
  30. namdo

    namdo

    Joined:
    Feb 23, 2015
    Posts:
    158


    Yes im using the latest one and use conversation variable is ticked. When the conversation tree ends, it goes back to gameplay. When i go back to that conversation, i have to start from the beginning of the convo again. The only time it saves the convo, is if i press the x button on the screen. when i go back to the convo then, it starts from where it stopped.


    Technically that's the way its supposed to work. However i still want to be able to see day 1's convo. I want to be able to read all the convo ive had with this person. like just opening your phone to read your messages. you should be able to see the previous messages like a log.
     
  31. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    I think I understand now. Please check this version. I also included the updated TextlineDialogueUI.cs that's in the latest release of Textline because it makes the code in SMSDialogueUtility.cs cleaner.

    Essentially, you want the conversation to stall until the next day; you don't want it to end. To do this, I included a tiny custom sequencer command (1 line of real code) that checks the value of a dialogue database variable named "Day" against a specified value. If Day isn't at least equal to the specified value, it just stalls the conversation. Otherwise it allows the conversation to continue.

    The example also has a new button to increment Day.
     

    Attached Files:

  32. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    Hi, I have another small problem.

    SetContinueMode(true) is not reset after using it on a Child Node.
    The "continue" button also remains for the next Child Node, even if it has not been spanned (not always).
    SetContinueMode (false) is not a good solution (the typewriter effect no longer runs).
    Is there another solution?
     
  33. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Hi @WILEz1975 - It sounds like the node with SetContinueMode(false) maybe needs more in the Sequence field, such as:
    Code (sequencer):
    1. SetContinueMode(false); {{default}}
    At runtime, "{{default}}" is replaced by the Dialogue Manager's Default Sequence. Otherwise the duration of the Sequence is only 1 frame (just enough time for SetContinueMode(false) to run), which doesn't give the typewriter any time to type.

    I've attached an example scene.
     

    Attached Files:

    WILEz1975 likes this.
  34. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    Thanks a lot. It works!
     
  35. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Happy to help!
     
  36. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Play Last Epoch at PAX South

    At PAX South today? Visit Eleventh Hour Games in Booth #10029 and play Last Epoch, made with the Dialogue System, and the game that's been called the next great fantasy ARPG.

     
  37. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    HI, another little question.

    Lua use SendMessages? Therefore can I send only one parameter?
     
  38. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Hi @WILEz1975 - No, Lua does not use SendMessage. (Sequencer commands do not use SendMessage either, except for the SendMessage() sequencer command.) You can use as many parameters as you want for Lua functions or sequencer commands. Here's an example:

    Code (csharp):
    1. void Awake() {
    2.     Lua.RegisterFunction("GetTitle", this, SymbolExtensions.GetMethodInfo(() => GetTitle(string.Empty, false, false)));
    3. }
    4.  
    5. string GetTitle(string surname, bool female, bool married) {
    6.     if (female && married) return "Mrs. " + surname;
    7.     else if (female && !married) return "Miss " + surname;
    8.     else return "Mr. " + surname;
    9. }
    The GetTitle() Lua function above takes three parameters: (string, bool, bool).
     
  39. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Inkborne Tales' When Silence Fell Now Available

    Check out When Silence Fell, a beautifully-written and atmospheric interactive novel made by Inkborne Tales using the Dialogue System for Unity:



    It's available now on the Apple App Store and Google Play.
     
  40. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288

    Thanks for the reply.
    I would have another question.

    The methods invoked by LUA are "generic" that is, the first method that is found with that name is executed ... can not point to a specific MonoBehaviour on a specific gameObject?

    From this:


    To this
    How could it be done?
     
    Last edited: Jan 23, 2019
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    We may be talking about different things. When you register a function with Lua, you register a specific C# method in a specific script on a specific GameObject.

    Are you using the SendMessage() sequencer command instead? If so, then this command works almost exactly like Unity's SendMessage() method. It executes the method on every script that has the method on the specified GameObject.
     
  42. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    Oh alright. I think that I have understand.
    So I should dare a different name to each method and record them all ...

    No, I'm not using SendMessage but a normal function.





    But he is called by different actors in different dialogues, each with his script. Because this script is placed on a lot of gameObjects (characters).

    Now I always run on the same script, (I guess) or the one that is last recorded that overwrites the previous ones. If I understood correctly.

    I do not know how to solve. I have a lot of characters that should always perform that "on themselves" function.
     
    Last edited: Jan 23, 2019
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Instead of a Lua function, I recommend using a sequencer command. (See Cutscene Sequences.) You can convert your code to a custom sequencer command. The Dialogue System includes a template script, and they're easier to write than Lua functions. In the sequencer command, you can easily access the speaker's transform. For example:
    Code (csharp):
    1. public class SequencerCommandSpeakAnimation01 : SequencerCommand {
    2.     IEnumerator Start() {
    3.         var time = GetParameterAsFloat(0);
    4.         print(speaker.name);
    5.         var thisCharMov = speaker.GetComponent<CharacterMovements>();
    6.         if (thisCharMov) {
    7.             // etc.....
    8.         }
    9.         yield return new WaitForSeconds(time);
    10.         Stop();
    11.     }
    12. }
    Then set the dialogue entry's Sequence field to something like:
    Code (sequence):
    1. SpeakAnimation01(1)
     
  44. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    288
    I'll check on Cutscene Sequences, tnx.
    For now, I've solved using a Manager class and a static activeActor variable (that is assigned to each dialogue beginning) that performs the LUA functions only on the currently active actor scripts.
     
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    @WILEz1975 - Okay, understood. BTW, you can also add certain special methods such as "OnConversationStart", "OnConversationLine", and "OnConversationEnd" to a script on the Dialogue Manager or either of the primary conversation participants. See the ConversationLogger.cs script for an example.
     
  46. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    i2 Localization Integration Updated

    The latest version of i2 Localization, 2.8.11, has a breaking API change. If you use the Dialogue System's i2 Localization integration and want to update to 2.8.11, you can download an updated support package from the Dialogue System Extras page.
     
  47. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    3,428
    @TonyLi I'm having trouble getting this integration fully working. I'm trying to get it all working on the Wii U and there are a couple of issues I'm seeing.

    First, in the video you state that the Standard Scene Transition Manager is no longer needed because EMM will handle scene transitions. However, if I simply follow the instructions in the video, a Scene Portal immediately loads the destination scene and does not go through EMM's LoadingScene.

    Second, I added a custom PlayerPrefsSavedGameDataStorer to the DialogueManager object, but the functions in there never get called. I put Debug statements in StoreSavedGameData() and RetrieveSavedGameData() functions and neither of them are output. Here is what my DialogManager game object looks like:

    upload_2019-1-25_6-36-23.png

    I made sure I have the scripting define PIXELCRUSHERS_SAVESYSTEM added as well. Any ideas?

    [EDIT]
    I just found out that if I press F5 for quick save that it finally calls the StoreSavedGameData() and RetrieveSavedGameData() functions. So, not sure why they don't happen on Scene Portal. I'll investigate further while I await a reply.
     
    Last edited: Jan 25, 2019
  48. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    92
    Tony,
    How hard is it if I want dialog from different actors showing up in different UI--all in the same conversation. For instance, pretend you have the old cartoon devil and angel on your shoulders making comments and/or participating in the player's conversation with another actor. In that case, you'd want, say, the devil and angel's conversation nodes showing up in speech bubbles near them while the main actor's words showed up in the regular UI?
     
  49. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,352
    Hi @bradbecker - Here are the steps:
    1. Use the Standard Dialogue UI system. (This is the default; you're almost certainly already using it.)
    2. Add a Dialogue Actor component to the actor.
    3. Set Dialogue UI Settings > Subtitle Panel Number to Custom.
    4. Assign this prefab to Custom Subtitle Panel: Assets / Pixel Crushers / Dialogue System / Prefabs / Standard UI Prefabs / Templates / Bubble / Bubble Template Standard UI Subtitle Panel.
    That actor will now use an instantiated copy of Bubble Template Standard UI Subtitle Panel, which is a generic-looking overhead cartoon bubble. If you want to customize it, add an instance of the prefab as a child of the actor. Then customize it to look the way you want, and assign it to the Dialogue Actor's Custom Subtitle Panel field.

    @magique - I'll check this and reply back soon.
     
  50. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    3,428
    Also, I've got UCC Saver setup on my Opsive character, but after Quick Save, the camera is not correct. The camera remains in the original position and the character is off somewhere else. I added a PositionSaver component to the camera, but that didn't help.