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:
    12,694
    Hi - You can read all about the Dialogue System's Ink integration here: Ink Integration

    And you can try it out before buying by using the Dialogue System's evaluation version.

    Unlike the other formats that the Dialogue System imports into a native Dialogue System dialogue database, the Ink integration runs Inkle's Ink For Unity plugin under the hood. The integration acts as a front-end that handles the UI, triggers, and interfacing with other Dialogue System features.
     
  2. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Wow, amazing, thank you.
     
    TonyLi likes this.
  3. MatrixNew

    MatrixNew

    Joined:
    Apr 16, 2020
    Posts:
    80
    I'm sorry, but the CSV file categorically does not suit me. show where to click to export to xlsx file. Thank you.
     
  4. DavidRodMad

    DavidRodMad

    Joined:
    Jan 26, 2015
    Posts:
    13
    TonyLi likes this.
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    The Dialogue System imports xlsx. It does not export xlsx. A different asset may suit you better.
     
  6. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    About the RPG Builder integration.
    Is it possible that the save doesn't include Dialogue System's variable?

    Just validating before going too deep create other solutions :p

    The reason I need it is mostly that I can't check if an RPGB quest is done because it creates a null reference if the player doesn't know it yet. So variables become very useful to do those checks.
    Edit: Meanwhile I made a checkup on start

    Code (CSharp):
    1.         if(Character.Instance.CharacterData.Quests.Count != 0)
    2.         {
    3.             foreach (var item in Character.Instance.CharacterData.Quests)
    4.             {
    5.                 if (item.questID == 8 && item.state == QuestManager.questState.completed) DialogueLua.SetVariable("CampfireIsDone", true);
    6.             }
    7.         }
     
    Last edited: Jan 13, 2023
  7. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi -

    1. Make sure you're using the latest integration from the Dialogue System Extras page.

    2. Use the preconfigured Dialogue Manager prefab in Assets > Pixel Crushers > Dialogue System > Third Party Support > RPG Builder Support > Prefabs. I recommend making a prefab variant of this prefab. That way you can customize it without worrying about overwriting your customizations when you import an updated integration package.
     
    mick129 likes this.
  8. GrassWhooper

    GrassWhooper

    Joined:
    Mar 25, 2016
    Posts:
    109
    hey small questions about the SMSDialogueUI

    1.is there a way for it to persist/keep its data across multiple conversations?
    when i start a new conversation, the currently displayed messages will vanish basically.
    2.if i were to create a phone "chat" with multiple people, is there any way you'd recommend to store the data?
    say player spoke to npc A, and NPC B and NPC C and each one has their "chat windows"
    3.is there a way to quickly modify/change the active dialogue system ui? (close the active one, then open the new one?)(the overrideui component, sadly does not close the active ui) (calling the Close function on DialogueUI instances, does not hide it nor close it, it stays visible)
    4.Is there a way to switch dialogue uis in the middle of a conversation?
    i have created a lua function that assigns

    Code (CSharp):
    1. public void UseUI(string newUIName){
    2. AbstractDialogueUI myNewUI = //find the newUI from a list in the class;
    3. var abs = DialogManager.instance.dialogueUI as AbstractDialogueUI
    4. abs.gameObject.SetActive(false)
    5. myNewUI.gameObject.SetActive(true)
    6. DialogManager.instance.dialogueUI = myNewUI.GetComponent<IDialogueUI>();
    7. }
    then i registered this function as a lua function, i noticed that, calling this function (From lua side) sort of fails, the text simply no longer continues, or ever shows on the new ui, and i am stuck just watching if that makes sense.

    any suggestions?
     
    Last edited: Jan 13, 2023
  9. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Yes. Tick the SMSDialogueUI's Use Conversation Variable checkbox. Before starting the conversation, set the DS variable "Conversation" to the title of the conversation.

    Would it work like a phone's text messaging app? Those apps typically show one conversation at a time, although you can go back and switch to a different conversation at any time. The SMSDialogueUI and Textline starter project (available on the Dialogue System Extras page) both work like that.

    I'm not sure exactly what you're trying to do, but if you want to change UIs mid-conversation you should set the current conversation view's dialogue UI:

    Code (csharp):
    1. DialogueManager.conversationView.dialogueUI = myNewUI.GetComponent<IDialogueUI>();
    If you're running multiple conversations in parallel (not just switching between them sequentially), you'll need to access the correct conversationView from DialogueManager.instance.activeConversations. It doesn't sound like you're doing this, though, so you can probably disregard this paragraph.
     
    GrassWhooper likes this.
  10. GrassWhooper

    GrassWhooper

    Joined:
    Mar 25, 2016
    Posts:
    109
    Thank you for the detailed response

    about this point, i am not sure how it will effect the save system, perhaps i need to extend it even further, but i found that i need to extend the SMSDialogueUI, so that once we "Open", we cache the messages, then reassign the instantiated messages to the cloned/cached messages, now when i open the SMSDialogueHelper, i get all of the messages from the last conversation back (i still need to extend it further, so it continiously caches the messages).

    i am disliking the fact that i need to store the full game object, as that would make saving difficult, but i guess it'll do for now, until i tackle the saving system

    Code (CSharp):
    1.  
    2. public override void Open()
    3.     {
    4.         List<GameObject> clonedMessages = new List<GameObject>();
    5.         if (!destroyOldMessages)
    6.         {
    7.             foreach (var msg in instantiatedMessages)
    8.             {
    9.                 var cloned = GameObject.Instantiate(msg, msg.transform.parent);
    10.                 cloned.transform.localPosition = msg.transform.localPosition;
    11.                 cloned.transform.localRotation = msg.transform.rotation;
    12.                 cloned.transform.localScale = msg.transform.localScale;
    13.                 clonedMessages.Add(cloned);
    14.                 var typer = cloned.GetComponentInChildren<TextMeshProTypewriterEffect>();
    15.                 typer.playOnEnable = false;
    16.             }
    17.         }
    18.         base.Open();
    19.         if (!destroyOldMessages)
    20.         {
    21.             instantiatedMessages = clonedMessages;
    22.         }
    23.     }
    -------------------------------------------
    basically, the game will have multiple different DialogueUIs and i thought it'd be a good idea to have the ability to switch in the middle of the conversation, through some lua, so designers do not get lost having to call external code and whatnot.

    i am unsure why, but assigning both worked perfectly.

    basically i ended up with the following

    Code (CSharp):
    1.     public void ChangeDialogueUI(string s, bool isMidConv)
    2.     {
    3.         var newUI = GetUI(s);
    4.         if (!newUI)
    5.             return;
    6.  
    7.         if (DialogueManager.instance.conversationView != null && isMidConv)
    8.         {
    9.             ChangeCurrConversationUI(newUI);
    10.         }
    11.         else
    12.         {
    13.             ChangeCurrDialogueUI(newUI);
    14.         }
    15.     }
    16.  
    17. private void ChangeCurrConversationUI(AbstractDialogueUI newUI)
    18.     {
    19.         AbstractDialogueUI currConvUI = DialogueManager.instance.conversationView.dialogueUI as AbstractDialogueUI;
    20.         if (currConvUI == null)
    21.             return;
    22.         if (currConvUI.name == newUI.name)
    23.             return;
    24.         if (currConvUI.isOpen)
    25.             currConvUI.Close();
    26.         newUI.Open();
    27.         DialogueManager.instance.conversationView.dialogueUI = newUI;
    28.         DialogueManager.instance.dialogueUI = newUI;
    29.     }
    30.     private void ChangeCurrDialogueUI(AbstractDialogueUI newUI)
    31.     {
    32.         AbstractDialogueUI currUI = DialogueManager.instance.dialogueUI as AbstractDialogueUI;
    33.         if (currUI.name == newUI.name)
    34.             return;
    35.         if (currUI && currUI.isOpen)
    36.             currUI.Close();
    37.         newUI.Open();
    38.         DialogueManager.instance.dialogueUI = newUI;
    39.         if (DialogueManager.instance.conversationView != null)
    40.         {
    41.             DialogueManager.instance.conversationView.dialogueUI = newUI;
    42.         }
    43.     }
    ---------------------------------------------
    and yeah, another feature that i am intending to make is to have a sort of "mini phone" that the player can pull out, and talk to npcs with it, or recieves messages on it.

    currently i feel its doable by extending the DialogueSystem, Perhaps, when i pull up the phone, and select the NPC i am talking to, i'd have all of the previous conversations with the given npc stored somewhere, and i load them at that moment, and feed them to the extended SMSdialogueSystem and place them in the "instantiatedMessages".

    no idea what variables to store, but thats something i'll figure out eventually i guess.
     
  11. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Hi! First of all, thank you for creating Dialogue System, I love it!
    I have an issue with the selector: at the moment I'm selecting the target at "Center of screen" but I would like to select it just when the NPC is in front of the player, not when back.
    1-Do you have any advice to achieve this?
    2-How can I set the "Custom position"? I checked the docs but couldn't find anything about it.
    Thanks
     
  12. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi - Please take a look at the code at the bottom of SMSDialogueUI.cs. It saves and restores conversation states, automatically instantiating messages from saved conversations. You probably don't need to use your code above. If you're using the Dialogue System's save system, it should be automatic. (Make sure to set the Conversation variable before starting the conversation.) If you're not using the save system, you can call RecordPersistentData() and ApplyPersistentData() in your own code.
     
    GrassWhooper likes this.
  13. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi - Thanks for using the Dialogue System! If the player is represented by an onscreen character (e.g., third person view), you may prefer to use a Proximity Selector.

    You won't need to set Custom Position if you're using Proximity Selector. If you want to use Selector with a custom position, in a script's Update() method set the property Selector.CustomPosition.
     
    fax58 likes this.
  14. coolco

    coolco

    Joined:
    Oct 5, 2020
    Posts:
    2
    Hi, I want to execute a custom C# function and see how to register that but how can I obtain the current actor (NPC) gameObject? It would seem like I need to pass it from the lua code somehow?
     
  15. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Thanks, I didn't realize I could have set the second collider on the NPC :)
     
  16. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi - Assuming the NPC is the conversation's conversant (e.g., assigned to Dialogue System Trigger's Conversation Conversant field - see Character GameObject Assignments), you can use the property DialogueManager.currentConversant. If it's the conversation's actor, use DialogueManager.currentActor. Or you can pass a GameObject name as a string to your C# method and use GameObject.Find() or GameObjectUtility.GameObjectHardFind().

    Glad to help!
     
  17. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    I have everything working great, just got one last (I hope!) question.

    I use the RPGB integration and want to open the QuestLog (or quest tracker) that we can open by pressing "L"

    I'm testing many directions like with QuestLog but I can't find to pinpoint the exact way of opening it via code. When you have a moment could you point me to the right direction?

    Thanks!
     
  18. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi! Make sure you're using the 2022-01-13 or later version of the RPG Builder integration (available on the Dialogue System Extras page). Then check the setup steps in the Main Menu Scene Setup section. If you're not starting from the quest log window prefab in the RPGB integration's Prefabs folder, add a QuestLogWindowDisplayPanel component and QuestLogWindowHotKey component to your quest log window.
     
    mick129 likes this.
  19. GrassWhooper

    GrassWhooper

    Joined:
    Mar 25, 2016
    Posts:
    109
    oh very interesting thanks a lot, i checked it out, and if i understood correctly, i need to call the "SaveSystem.SaveToSlot()" at the end of the conversation? and before it starts i need to call DialogueSystem.SetVariable("Conversation",conversationName)?

    ----
    but i have a tiny small other question
    so, in our game we have a sort of our own unique interactions system, that mainly uses bools.
    my goal is to have my system, read variables from the DialogueSystem variables, and when these variables change, in dialogue system, my interactions systems just reads those and acts based on them.

    the best idea i could think of, is collecting the variables from the Database, and then using the

    AddLuaObserver(string luaExpression, LuaWatchFrequency frequency, LuaChangedDelegate luaChangedHandler)
    RemoveLuaObserver(string luaExpression, LuaWatchFrequency frequency, LuaChangedDelegate luaChangedHandler)

    functions, i'd be able to know, when these variables change from the dialogue system.

    however there are 2 issues
    1.i did read in some other posts that recommend avoiding them, (i have to use them in OnUpdate, because essentially these variables might change at any point in the game).
    2.only the last observer is called, all other observers calls are sort of ignored.

    Code (CSharp):
    1.         private bool ValidateVariable(string s, out Variable v)
    2.         {
    3.             bool isGoodVar = false;
    4.             v = db.GetVariable(s);
    5.             if (v != null && v.Type == FieldType.Boolean)
    6.                 isGoodVar = true;
    7.             return isGoodVar;
    8.         }
    9.  
    10. private void OnUpdatedBool(LuaWatchItem luaWatchItem, Lua.Result newValue)
    11.         {
    12.             Debug.Log("Recieved, OnUpdatedBool from lua :: " + luaWatchItem.LuaExpression);
    13.             bool newVal = newValue.asBool;
    14.             string totalExpr = luaWatchItem.luaExpression;
    15.             string b = pairs[totalExpr];
    16.             if (!string.IsNullOrEmpty(b))
    17.                 conditionsSource.UpdateCondition(b, newVal);
    18.         }
    19.  
    20. private void RefreshCondsSource(bool addObserver)
    21.         {
    22.             conditionsSource.ClearConditions();//Interactions System Conditions
    23.  
    24.             foreach (string b in boolsToWatch)//boolsToWatch = Names of variables i want to watch
    25.             {
    26.                 if (ValidateVariable(b, out Variable v))
    27.                 {
    28.                     string expr = GetLuaVarExpr(b);
    29.                     if (addObserver)
    30.                     {
    31.                         Debug.Log("Added Observer To " + expr);
    32.                         DialogueManager.AddLuaObserver(expr, LuaWatchFrequency.EveryUpdate, OnUpdatedBool);
    33.                     }
    34.                     string totalExpr = "Return " + expr;
    35.                     pairs[totalExpr] = b;//Store the total expression in a dictionary so i can use it for filtering
    36.                     conditionsSource.AddCondition(b, v.InitialBoolValue);
    37.                     //example of totalExpr = "Return Variable['hasPickedUpKey']"
    38.                     //example of partial expr (what we register) "Variable['HasPickedUpKey']"
    39.                 }
    40.             }
    41.         }
    basically what is happening is that the OnUpdatedBool is only called at the final registeration, rather than for all observers.

    upload_2023-1-15_12-0-38.png

    upload_2023-1-15_12-1-20.png
     
  20. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    If you want to use SMSDialogueUI (you could always use your own dialogue UI subclass if you prefer), these are the steps. Let's say you havde two NPCs, Adam and Bob, and two conversations, also titled "Adam" and "Bob". Assume you have a variable smsDialogueUI that points to your SMSDialogueUI.

    1. Tick the SMSDialogueUI component's Use Conversation Variable checkbox.

    2. Before starting the conversation, set the "Conversation" variable to a conversation title:
    Code (csharp):
    1. DialogueLua.SetVariable("Conversation", "Bob");
    3. Check if the dialogue UI already has a history of messages for this conversation. If so, resume it. Otherwise start it fresh:
    Code (csharp):
    1. if (DialogueLua.DoesVariableExist("DialogueEntryRecords_" + "Bob")) // We have a history...
    2. {
    3.     smsDialogueUI.OnApplyPersistentData(); // ... so resume the conversation:
    4. }
    5. else
    6. {
    7.     DialogueManager.StartConversation("Bob"); // ... otherwise start it fresh.
    8. }
    4. To exit the conversation:
    Code (csharp):
    1. smsDialogueUI.RecordPersistentData(); // Record conversation history.
    2. DialogueManager.StopConversation();
    That would use polling, which as you mentioned isn't efficient. I recommend using events instead. Write a C# method that sets a Dialogue System variable and also invokes a C# event. Example:

    Code (csharp):
    1. public event System.Action<string> VariableChanged;
    2.  
    3. public void SetDSBool(string variableName, bool value)
    4. {
    5.     DialogueLua.SetVariable(variableName, value);
    6.     VariableChanged?.Invoke(variableName);
    7. } // (and similar for other value types)
    8.  
    9. void OnEnable()
    10. {
    11.     Lua.RegisterFunction(nameof(SetDSBool), this, SymbolExtensions.GetMethodInfo(() => SetDSBool("", false)));
    12. }
    See Registering Lua Functions for details related to Lua.RegisterFunction. There's also a starter template in the Templates/Scripts folder.

    In your conversations or elsewhere, use SetDSBool() to set DS variable values.
     
    GrassWhooper likes this.
  21. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    Thank you for all the help.
    Next month I release Brinefall on Steam with your asset :)
     
    TonyLi likes this.
  22. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Hi! Sorry to bother, but I'm just starting out using DS.
    Changing the color on the proximity selector does not change the name and message text color on the Basic Standard UI Selector Element. If I try to edit the prefab, the script doesn't show any data

    Thanks!
     

    Attached Files:

  23. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi! The colors on the Proximity Selector itself are only used if you're using the old IMGUI display that's built into Proximity Selector. You're using the Basic Standard UI Selector Elements instead, which is much better. Try this:
    1. If you're using Unity 2022.2, import the package below (see direct download below).
    2. Duplicate the Basic Standard UI Selector Elements prefab. (This way you won't lose your customizations when you update DS.)
    3. Assign your duplicate to the Dialogue Manager GameObject's Instantiate Prefabs component > Prefabs list in place of the original.
    4. Edit your duplicate. Set these colors: upload_2023-1-15_17-1-25.png
    5. You can remove the Reticle In Range & Reticle Out of Range GameObjects if you prefer.

    Are you using Unity 2022.2. There's a bug in Unity 2022.2; the Dialogue System Extras page has a workaround (direct download) that will also be in the next regular DS release.
     
  24. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Thank you! Yes I'm using 2022.2 and I couldn't see any variables on the script ;)
     
  25. alexrau

    alexrau

    Joined:
    Mar 1, 2015
    Posts:
    80
    Using EmeraldAI and want to have the AI stop when conversation starts and want to resume movement after conversation).

    I am using EmeraldAI integration and I am able to get the Stay function to work.

    EmeraldAIStay("NPC");


    however it is not clear to me what script to call to resume. I thought it would be to set the wandertype, which I am able to do, but nothing happens. Also nothing happens if instead of AIStay I use SetEmeraldWander to Stationary.

    SetEmeraldWander("NPC", "Dynamic")
     
  26. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi! Use SetEmeraldWander() for both. When the conversation starts, use SetEmeraldWander("NPC", "stationary"). When the conversation ends, use one of the other values such as SetEmeraldWander("NPC", "waypoints").
     
  27. alexrau

    alexrau

    Joined:
    Mar 1, 2015
    Posts:
    80
    Thanks for the direction. Tried it and it sort of works, but if the AI is in motion setting it to stationary does not make it stop. EmeraldAIStay("NPC") will make it stop, but then not restart. Posted same question to Emerald AI, since maybe it is more my usage of that asset.
     
  28. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Use EmeraldAIFollow("NPC", "player", "Companion") to stop the NPC. This sets the NPC to Companion mode and follows player.

    Use SetEmeraldBehavior("NPC", "Aggressive") (or "Passive" or "Cautious") to set the NPC to non-Companion mode and allow it to resume its regular movement behavior.

    I've attached an example scene. It has two buttons at the bottom that run Lua functions.

    Also, the Dialogue System Extras page has an updated Emerald AI integration package to accommodate Emerald AI's change of the name of its Faction Data asset.
     

    Attached Files:

  29. alexrau

    alexrau

    Joined:
    Mar 1, 2015
    Posts:
    80
     
  30. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Glad to help!
     
  31. claudius_I

    claudius_I

    Joined:
    May 28, 2017
    Posts:
    254
    Hello Tony.
    I starting using Dilaogue system with Salsa and textSync and worked very well.
    But i have a question about some dialogues. In my project some dialogues are thoughts and the character dont need to move lips. there is a way to avoid this.

    Thanks
     
  32. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi - You could assign those lines to a new actor, for example named PlayerThoughts. Create a GameObject for that actor as a child of the player. Add an Audio Source but no SALSA components:

    upload_2023-1-23_8-40-50.png

    For those lines, you could use an AudioWait() sequencer command instead of SALSA() sequencer commands.
     
    claudius_I likes this.
  33. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Voodoo Detective Chosen as IGF 23 Honorable Mention for Visual Excellence

    Congratulations to Short Sleeve Studio! Voodoo Detective received an IGF23 Honorable Mention for Excellence in Visual Art. It's made with the Dialogue System for Unity and features an all-star voice cast and live-recorded music composed by Peter McConnell, the composer of Grim Fandango, Monkey Island, and Psychonauts. You can play it on PC, Mac, Linux, mobile, and Nintendo Switch.

     
  34. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Clunky Hero -- Out Now

    Chaosmonger's comedic metroidvania Clunky Hero, made with the Dialogue System, is out now on Nintendo Switch, Xbox, PlayStation, Steam, and GOG. If you like platformers with a sense of humor and a unique art style, check it out.

     
  35. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    GRUNND - Out Now

    Enjoy dark mysteries and weird fiction? Sektahouse just released the narrative adventure GRUNND, made with the Dialogue System for Unity and inspired by Kafka and Lynch. Check it out on Steam.

     
    mick129 likes this.
  36. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    It took me a while to figure out the source but I have this error. It happen only when I build with the manager in the game and it is solved if I delete from the scene.
    My setup is the following

    Main Menu (scene 0)
    Brinefall (Scene 1 and the main game) -> This is where Dialogue for Unity is installed.

    My question is, is it problematic if the manager doesn't start from the main menu? (So far for me everything work). I made it this way to use scene specifics events.

    And second question, I don't really expect a positive answer but just in case, have you ever seen the error below and do you have a quick way to find the source?
    Edit: I'm still not even sure its related to the asset but something seems to try to reach an asset that doesn't exist anymore.

     
    Last edited: Jan 27, 2023
  37. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi! Sorry, there's not enough info to help with that error message. Maybe your project has some asset or script that does asset processing and is removing an asset during the build process.

    Regarding the Dialogue Manager, please put it in the main menu scene. It's needed there to integrate with character loading. Don't connect scene events or UnityEvents to the Dialogue Manager, unless those UnityEvents are also a part of the Dialogue Manager's hierarchy (e.g., a Dialogue System Events component on the Dialogue Manager). For more info, see this related article: How To: Manage Player Controls and Scene Changes. You can usually use sequencer commands to accomplish the same thing without having direct inspector-assigned references to the Dialogue Manager GameObject.
     
    mick129 likes this.
  38. Mythran

    Mythran

    Joined:
    Feb 26, 2013
    Posts:
    85
    Hello,
    Is there a way to replace a a part of a substring in the Dialogue Text based on a condition?
    "and i was eager to meet the one i dedicated my life to"
    The above sentence links to "." or ", even if he has less noble intentions" based on a condition,
    but this is noticeable as the nodes text appears in the next line and not in the same.

    Also i'm starting quite confusing nodes as i'm making complex dialogue links.
    Is there something similar to portals to link nodes?

    Thanks
     
  39. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Use the Conditional() function in a [lua(code)] markup tag. But first you'll want to import the patch attached to this reply; it has an improvement to Conditional() that's in version 2.2.34 (which itself should be available on the Asset Store by Monday morning).
    For example, say you've defined a Number variable named "Trust" in your dialogue database. If it's negative, the player doesn't trust that NPC. Then you can set the Dialogue Text to:
    • Dialogue Text:
      I was eager to meet the one I dedicated my life to[lua(Conditional(Variable["Trust"] < 0 , ", even if he has less noble intentions"))].

    Three features will help:
    1. Group nodes
    2. Group boxes
    3. Cross-conversation links
    Use group nodes as "hubs" to reduce the number of links needed between nodes. To turn a node into a group node, tick the node's Group checkbox. This is the most common and effective way to reduce link arrows.

    You can also lasso a bunch of nodes and hold Ctrl as you release the mouse to put them into a grouping box. You can then label this box and move it around. This helps organize branches of your conversation.

    Or you can split up the conversation into multiple smaller conversations that are easier to manage, and use cross-conversation links between them (often in conjunction with group nodes). To add a cross-conversation link, inspect a node. From the "Links To:" dropdown, select "(Another Conversation)".
     

    Attached Files:

  40. Jonathan-Westfall-8Bits

    Jonathan-Westfall-8Bits

    Joined:
    Sep 17, 2013
    Posts:
    259
    If anyone has issues with Unity 2022.2 causing some of the Dialogue System components to not render in the inspector and make errors inside of the console this post explains the issue and a setting in Unity to fix most of the components not rendering. The settings is a simple checkbox you click.

    Couldn't see a message about this in the forum so I apologize if this bug is already fixed or taken care of in a newer version of the Dialogue System. Currently using version 2.2.31 of the Dialogue System.
    Enjoy this detailed bug report.

    I upgraded Unity version from 2021.3.9f1 to 2022.2.4f1 and I noticed some of the scripts using custom property drawer have some bugs/errors printed out that make some of the Dialogue Systems components not render properly mainly in the inspector with components that rely on stuff that inherit from the Decorator Drawer class. Example is the HelpBoxAttributeDrawer class.

    Error code attached below shows the error I get when looking at a script in the inspector.
    error code.PNG

    Also attached an image showing what the inspector looks like when trying to view the component.

    inspector broken.PNG

    In the HelpBoxAttributeDrawer class in the override of the GetHeight function if you return a number directly instead of the current code in it the component renders correctly.

    You need to comment out the var helpBoxStyle and the lines that use it for it to work.
    Seems a Unity change messed with calling anything in the GUI class outside of the OnGui function.
    So the OnGui.Skin is breaking somethings when being called not directly in the OnGui fuction.

    Below shows what happens if you return a number and comment out the GUI.skin calls.
    inspector working.PNG


    I know this is due to Unity upgrading inspectors to the UI Toolkit and when IMGUI is used it is rendered in a IMGUI Container component inside a Visual Element used inside of UI Toolkit. Unity added new UI Toolkit stuff for CustomPropertyDrawers in the 2022 versions so I think it broke somethings that are messing with your Asset.

    The reason why I say that I know this is the case in the editor setting you can change a setting to use the original IMGUI system instead of the newer UI Toolkit for the inspector still. If you check this settings everything works fine.
    No errors and the components render properly like they should using the original IMGUI system.

    To find the option go to edit/project settings. It is under the Editor tab. It is usually the very last option at the bottom depending on if you have certain Unity Packages installed.
    Image below circling the option so you don't have to search for it.

    editor settings.PNG


    Hope this helps anyone that might run into this problem till a solution is found.

    For anyone using custom UI Toolkit visual elements worrying checking this box might mess things up well for the most part it won't effect custom UI Toolkit code. This should make it where everything is rendered in the IMGUI system only if no UI Toolkit code is trying to override it. If UI Toolkit is found on an inspector it will use Visual Elements instead to render that element.

    Due note this option only effects the inspector panel. If you make a custom editor window this editor option won't do anything to it, but if you coded the editor window in IMGUI it won't try to use the UI Toolkit at all so the above bug should only affect hopefully CustomDrawers in the inspector.

    Sorry for the very length post, but I wanted to make as detailed bug report/post about it so the issue can be solved and also make the debugging job of PixelCrushers a lot easier which makes his life and the people that use his asset lives a lot easier.

    Good day Unity community.
     
    TonyLi likes this.
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @cecilcruxis - Unity is aware of this bug in Unity 2022.2+. They have a issue tracker open to fix it. In the meantime, for Dialogue System versions 2.2.33 and earlier, there has been a workaround patch on the Dialogue System Extras page since December 22 when the bug was discovered.

    Version 2.2.34, which is available on the Asset Store, has a workaround already built into it.
     
  42. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Dialogue System 2.2.34 Released

    Version 2.2.34 is available on the Asset Store! This is a big release with lots of improvements, bug fixes, and updates to integrations.

    Release Notes:

    Core:
    • Changed: Conditional() Lua function now uses a bool for the condition parameter, not a string.
    • Improved: Added search bar to Dialogue System Trigger conversation selection, [ConversationPopup] attribute to allow filtering of conversation titles.
    • Improved: BarkGroupManager now has CancelAllBarks() method; can now pass null to MutexBark() to hide all barks in group.
    • Improved: AudioWait() sequencer command methods are now virtual.
    • Improved: Typewriter effects now accepts <c>\n</c> to represent newlines in Full/Quarter Pause Codes fields.
    • Improved: LocalizeUI now localizes TMP_Dropdown components.
    • Improved: Added DialogueManager.instance.overrideGetLocalizedText delegate hook.
    • Improved: StandardUIMenuPanel.SetResponseButton now sets response property before calling StandardUIResponseButton.SetFormattedText.
    • Improved: Now logs warning if StandardUIResponseButton text is blank.
    • Improved: ConversationModel.SetParticipants() is now public to allow changing conversation's actor & conversant GameObjects mid-conversation.
    • Improved: TextMeshProTypewriterEffect now calls ForceMeshUpdate with every character in case UI element is being animation (e.g., scale).
    • Improved: Now supports running in batch mode. (Define BATCH_MODE scripting symbol.)
    • Improved: Importers (articy, Arcweave, Chat Mapper) sync from any sync'ed DBs before importing.
    • Fixed: Implemented workaround for inspector bug in Unity 2022.2 - 2022.3.
    • Fixed: Issue with custom sequence field dropdown menu items.
    • Fixed: Continue() sequencer command now only advances its own conversation, not all active conversations, unless you pass 'all' as parameter.
    • Fixed: Subtitle panel Block Input Duration doesn't start until panel's Show animation has finished.
    • Fixed: Now uses localized name for portrait names that appear in Show On Conversation Start.
    • Fixed: Cached bark lines now observe markup tags.
    • Fixed: LuaConditionWizard inspector rendering when using Odin Inspector.
    • Fixed: Evaluation version's Welcome Window would set USE_YARN scripting define symbol, causing error when switching to Asset Store version if Yarn Spinner was not installed.
    • Fixed: DialogueSystemSaver.ResetGameState now clears quest tracker HUD.
    • Dialogue Editor: Link order is now shown on node link arrows by default. / Tooltip hover link order
    • Dialogue Editor: Added option to include conversation title in every dialogue entry row in voiceover script export.
    • Dialogue Editor: Added option to hide filtered-out actors in Actors section.
    • Timeline: Added Run Lua clip.
    Third Party Support:
    • Adventure Creator: Added Pause action, Force Cursor Visible During Conversations checkbox on bridge component.
    • Arcweave:
      • Added support for runtime import.
      • Team plan users can now download Arcweave project updates into importer using Arcweave web API.
      • Now observes character assignments dragged onto dialogue elements in Arcweave, unless overridden by "Speaker:name".
      • Now imports custom fields added to actors and locations.
      • No longer creates group nodes for connections without text.
      • Improved behavior of Merge checkbox.
      • Importer now handles null jumper elementId's.
    • Celtx:
      • Custom breakdown types now use custom type name for field title.
      • Multiple breakdowns in same node are now concatenated into the relevant breakdown field.
      • Added option for Gameplay elements to be imported as their own dialogue entry nodes.
      • Ink: Mixing Ink conversations and regular dialogue database conversations now allows regular conversations to fully evaluate all links.
    • i2 Localization:
      • Refresh button now clears internal list of which fields to include/exclude from localization.
      • Now disables checkboxes for fields that shouldn't be localized (e.g., Boolean, Number).
      • Now allows localization of Localization field types.
      • Added option to include conversation ID/title with custom field values in dialogue entry terms.
    • Localization Package:
      • Fixed issue with updating actor names when switching locales.
      • Added option for DialogueManager.GetLocalizedText() to use translations in the Localization Package's string tables.
    • Makinom: Start Conversation node can now specify a different starting entry ID.
    • ORK: Added orkGetQuestTaskStatus() Lua function.
    • Emerald AI: Finds proper location of new Faction Data asset.
    • PlayMaker: Fixed inconsistent line endings message caused by LuaTableEnum.cs.
    • RPG Builder:
      • Changed: rpgGainExperience() is now rpgAddSkillExperience().
      • Added Stop NPC During Conversation, Bypass Interaction Panel options to NPC Dialogue System setup. (See manual page for known issue.)
      • Added Lua functions: rpgAddCharacterExperience(); get/set RPGQuest states; get values of stats, abilities, skills.
      • Added rpgMerchant() and rpgTeleport() sequencer command.
      • Quest tracker is no longer shown in main menu scene.
      • Addressed issue with save system and respawning.
      • Added quest example to demo prefabs.
    • Text Animator: Updated for Text Animator 1.3.x.
    • TopDown Engine: Added AllowUINavigationDuringConversations component to re-enable input after closing Inventory Engine UI during conversation.
    • Yarn: Fixed import issue that set nodes' Sequence fields to Continue() when they shouldn't be.
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    GRUNND in PC Gamer's Five New Steam Games You Probably Missed (January 2023)

    Congratulations to Sektahouse! GRUNND, made with the Dialogue System for Unity, is at the top of PC Gamer's list of Five new Steam games you probably missed (January 2023). They write:
     
  44. GrassWhooper

    GrassWhooper

    Joined:
    Mar 25, 2016
    Posts:
    109
    hey there
    thank you for your previous support
    i have a small question
    do we have the following functionalities built in?

    1.Skipping Dialogue, in visual novels, we can basically click "skip" and it can keep skipping, until we reach a line that we have not read previously (or that a decision) whichever comes first
    2.Skipping Until A Decision, in visual novels, we can basically keep skipping until a dialogue ends, or until we a decision/choice/branching point where we have to make a decision.

    if yes, can you show some links that help us see it and control it or give a brief description?

    ----------------

    and one more functionality, can we lock certain decisions, behind a condition?
    say we have the dialogue system bool "hasPickedUpKey" and its true
    and when its true, we get 2 choices/decisions
    but if "hasPickedUpKey" is false,
    then we want to get Two choices on the screen, but has one of them be locked (unselectable) (and has different visuals).
    any idea how we'd approach that?

    i had the idea that i'd extend the DialogueUI, and in the conversation, i'd transition into a node that calls a function on the extended dialogue ui, that tells it "prepare to show locked decision on x", and once we enter the decision node, it overrides the response menu maybe, what do you think?
     
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @GrassWhooper - These are all fundamental, built-in features of the Dialogue System. They don't require any scripts or anything custom.
    Add a ConversationControl component to your dialogue UI. Add UI Buttons to your dialogue UI, and hook them up to any of these methods:
    • ConversationControl.ToggleAutoPlay: Toggles continue button mode between Always and Never.
    • ConversationControl.SkipAll: Skips all subtitles until response menu or end of conversation is reached.
    • (ConversationControl.StopSkipAll: Abort SkipAll.)

    Use Conditions. See:
    On the Dialogue Manager GameObject, set Display Settings > Input Settings > Include Invalid Responses and [em#] Tag For Invalid Responses. The [em#] corresponds to the Emphasis Settings in the Dialogue Editor's Database section > Database Properties > Emphasis Settings.

    You can also find more details about Conditions and invalid responses in this article:
    How To: Do Skill Checks in Conversations
     
    GrassWhooper likes this.
  46. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Hi!
    I would like to use the "Focus Template Standard Dialogue UI" but with persistence of the last NPC dialogue line.
    Or the "WRPG Template Standard Dialogue UI" but with only the last NPC dialogue line (not all of them).
    Which approach do you advice? Which is the easier, cleaner solution?

    Also another thing: every NPC should have a var to indicate if it is the first dialogue with the player. Manually adding a var for each NPC in the DB could be a bit tedious, is there a way with LUA to make the process easier?

    Thanks!
     
    Last edited: Feb 1, 2023
  47. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    You can do either. The easiest is probably to make a copy or prefab variant of the WRPG Template Standard Dialogue UI and UNtick the subtitle panel's Accumulate Text checkbox.

    You could use SimStatus. Or you could use variables. You don't have to define the variables in your DB ahead of time. If you haven't defined a variable, its value will default to nil. Say you have NPCs named Ann, Bob, and Carl. When Ann's conversation starts, you can check if, for example, Variable["Talked.Ann"] is true or not true:

    upload_2023-2-1_8-19-54.png

    I could also have variables "Talked.Bob" and "Talked.Carl", which I can easily filter in the Dialogue Editor's Variables section or the separate Variable Viewer window by setting the filter to "Talked." or enabling the option to group variables based on "." (e.g, "Talked."). On the other hand, if Ann has a lot of variables (Talked, Mood, Money, DiscussedJob, etc.), you could group them like Ann.Talked, Ann.Mood, Ann.Money, etc., so they'll all appear together.
     
    fax58 likes this.
  48. fax58

    fax58

    Joined:
    Dec 27, 2021
    Posts:
    42
    Beautiful, Thank you!
     
  49. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Glad to help!
     
  50. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Games From Quebec Event on Steam

    Check out several Dialogue System-powered games from Quebec available to buy or demo in Steam's Games From Quebec Sale, including:

    BIOMORPH (Lucid Dreams Studio)


    Brinefall (Qwerty Studio)


    Legends of Ethernal (Lucid Dreams)


    The Spirit and the Mouse (Alblune)


    And many more!