Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

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

  1. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    216
    Why don't all fields show up in inspector? (Pictures and Description)
    upload_2019-4-18_21-44-53.png
     
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    It keeps the Inspector from getting too cluttered. In the Templates section, Quests, Conversations, and Dialogue Entries have a Main checkbox next to each field. You can tick the checkbox to show the field in the main part of the inspector. Locations and Items don't, though. In a future version, I can add Main checkboxes for Locations and Items if there's demand for it.
     
  3. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Unity 2019 Note: Dialogue System, Timeline, and Assembly Definition Files

    Most people can ignore this post.

    If you are not using Unity 2019, you can skip this post.

    If you are not using the Dialogue System's Assembly Definition Files, you can skip this post.


    If you are using the Dialogue System's asmdefs on Unity 2019, please note: Timeline is now provided as a separate package. If you're using asmdefs, please add Unity.Timeline to the DialogueSystem asmdef:

    upload_2019-4-19_8-14-12.png
     
  4. Ekzalphantoss

    Ekzalphantoss

    Joined:
    Sep 27, 2016
    Posts:
    11

    But the thing is that I need the choice index rather than its text. I cannot differentiate via text because aside from the Dialogue system, the text is not stored anywhere so I can't compare it to find out the choice number.

    Actually nevermind, I just realized I can extend the StandardUIResponseButton to send its Sibling Index when clicked which would make differentiating between buttons easy
     
    TonyLi likes this.
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Good thinking. I was about suggest that. Another alternative is to check subtitle.dialogueEntry.id. This is the dialogue entry's unique ID in the conversation. I'm not sure exactly what you're using it for. If you need menu positions, your solution is best.
     
  6. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @RecursiveFrog - This patch offers the dropdown. The change will also be in the next version.
     

    Attached Files:

    RecursiveFrog likes this.
  7. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    @TonyLi I'm still confused as to how to do a proper setup for saving/loading scenes, doing scene transitions, and integrating with a controller like Invector. My main problem is I don't know just how the system moves components from scene to scene and where I should initially put those components. For example, for Invector it needs the following:

    vThirdPersonCamera
    vThirdPersonController
    vGameController
    vUI

    In my MainMenu scene I have the Save System and Dialogue Manager, which will be integrated with EMM. So, do I need my player objects all in this initial scene also? And if so, how do they get moved into the first level scene that loads? Or do I need exact copies of these components in each scene that is loaded? If so, how does the system know how to handle updating the copies in each scene?

    I just don't have a clear picture and I can't find this kind of information in the docs.
     
  8. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @magique - With the save system, it's best to have a separate player GameObject in each gameplay scene. For Invector, this means unticking the Locomotion > Use Instance checkbox.


    Changing scenes
    Change scenes using a ScenePortal component, the LoadScene() sequencer command, or SaveSystem.LoadScene(). These let you specify an optional spawnpoint in the new scene where the player will appear.

    The save system does this to change scenes:
    1. Tells all saver components in the current scene to save their state (e.g., positions, stats, etc.).
    2. Tells all saver components in the current scene that the scene will be unloaded.
    3. If the Dialogue Manager (or Save System) has a Scene Transition Manager component, plays the "leaving scene" transition (e.g., fade to black, load an intermediate loading scene, etc.).
    4. Async loads the new scene.
    5. Tells all saver components in the new scene to update their state from the save system's saved data.
    6. Scene Transition Manager plays the "entering new scene" transition (e.g., fade from black).
    In the case of the Invector player, in step #1 the player GameObject in the current scene saves its stats and inventory. In step 5, the (new) player GameObject in the new scene sets its stats and inventory according to the saved info.


    Saving a game
    When saving a game, the save system does this:
    1. Tells all saver components in the current scene to save their state (e.g., positions, stats, etc.).
    2. Serializes the saved data using whatever DataSerializer component is on the Dialogue Manager or Save System (e.g., JsonDataSerializer or BinaryDataSerializer).
    3. Writes the serialized data to a destination using whatever SavedGameDataStorer present (e.g., PlayerPrefsSavedGameDataStorer or DiskSavedGameDataStorer).
     
  9. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    OK, everything else makes sense, but I'm a bit fuzzy on this. If I already have an instance of the player in the scene to be loaded, what will specifying a spawnpoint do? Is it going to move that existing instance to the spawn point? So, if I don't specify a spawnpoint then it simply starts the player at the instance's position?
     
  10. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Yes, that's correct.
     
    magique likes this.
  11. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    I'm not quite getting expected results. I now have instances of the player, camera, etc. in both the start scene and the scene to be loaded using ScenePortal. However, when I go into the portal and the scene loads, the player falls through the floor. However, if I use a SpawnPoint instead of the instance's position then it works. So, I'll do it that way from now on.
     
  12. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Make sure that your scene has a player instance (and you're not instantiating it automatically from vGameController) and that its Use Instance checkbox is unticked.

    However, if you're happy to always use spawnpoints, that's a good way to go, and you can just leave it at that. It lets you consistently specify where to position the player. And it also supports multiple entrances into the scene. For example, when entering the tavern from the city street you want the player to spawn at the front door. But when entering the tavern from the sewers you may want the player to spawn in the tavern's cellar.
     
  13. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    I definitely have it that way so not sure why it has trouble when not using spawn points. But since the spawn point works, I will just go with that.
     
  14. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    350
    That's really cool, and it works great! Thank you for being so responsive, it's really encouraging and makes me glad I purchased the tool.

    Do you think it would be possible to support this kind of inspection in the SLATE integration? It would be really helpful across the board, in either situation I think.
     
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @RecursiveFrog - Yes, the dropdown is general-purpose; I plan to enable it for the SLATE integration and the PlayMaker integration in the next version.
     
  16. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    @TonyLi I've got everything mostly working, but have a question and an issue.

    First, for the Invector Player should we use both the stats saver and inventory saver? Or is only one of these supposed to be used?

    Second, I have an auto equipped sword in the player's hand in the first scene, but when I portal to a new scene, the weapon is no longer equipped. Both instances are set to Auto Equip, but when I look at the second scene's player after portaling, it no longer has auto equip checked.
     
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @magique - If you want to save both things, use both savers. Make sure you've assigned unique keys to each one or ticked Append Saver Type To Key.

    I should have this issue finally fixed in the next update.
     
  18. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Got it. I had them both, but I'm not sure about having a unique key or the append flag ticked.

    OK, I'm glad it wasn't just me. I will await the fix then.
     
  19. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Hi tonyly its me again. Regarding the menu prefab that I unchecked the singleton, the music and sound settings don't carry over to the new scene and when I adjust the music and sound settings in the new scene it doesn't work. It only works in the main menu scene. How can I fix it?
     
  20. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @dinaloraven234 - Create an Audio Mixer if you haven't already, and assign it to the Options components' Main Mixer fields.

    If music isn't playing when you change scenes, add a Timed Event component. Tick Activate On Start, and configure it to call the Music Manager component's PlayTitleMusic or PlayGameplayMusic methods as appropriate for the scene.
     
  21. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Hi @TonyLi can you make the options menu have a singleton settings like the input device menu but not the whole menu system to avoid tweaking my settings for every scene
     
  22. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Save your customized MenuSystem prefab as a new prefab, and use that prefab in your scenes. That way you only need to tweak settings for the prefab.
     
  23. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Hi @TonyLi the mixer that I have in my scene is the master mixer included in the menu system
    Hi @TonyLi I have a audiomixer which is your master mixer ung the menu prefab but still when I go to new scene and try to adjust the settings nothing happened but I fixed the gameplay sound to play in their appropriate scenes using your timed event as you suggested.
    I think the only solution for it is to make the music manager or the options script have a singleton separate from the menu script just like the Input device manager of the dialogue manager
     
  24. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    I recommend opening an Audio Mixer window so you can view the audio mixer levels at runtime. Notice when you move the slider in the Options menu that the levels go up and down.

    I'm not able to reproduce this. I put the latest version of the Menu Framework on the Extras page (direct download) I don't think it has anything new, but it ensures that we're both using the same code. If you customized the MenuSystem prefab, don't overwrite it if you import this package. (Make a backup first, too.)

    For example, in the title menu if I slide the music down to 50%, the Audio Mixer levels go to 50%. When I change to the gameplay scene, the Audio Mixer level is still 50%. And if I open the pause menu and go to options, the slider is 50%.
     
  25. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Hi @TonyLi this is the master mixer I'm talking about and I also opened the audio mixer when I use the slider for the music the slider in the audio mixer also slides and it works but when I slide down the slider for the effects sound the slider in the audio mixer slides down but still the sound effects can be heard
     
  26. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Here's the master mixer I'm talking about that's included in your prefab
     

    Attached Files:

  27. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Have you assigned the SoundFx channel to your Audio Sources? Otherwise they won't use the audio mixer at all.
     
  28. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    I haven't checked yet if I assigned it. I'll check it later
     
  29. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    Would anyone happen to know why this box collider doesnt seem to register correctly with DS?



    Maybe it's a stupid question, but I'm trying to incorporate the quest log to the core ui and it's been a bit of a pain.

    Thanks!
     
  30. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @brad_penbach - It looks like the 'N' GameObject is on the "UI" layer. You'll either need to switch it to a layer that's covered by the Selector's Layer Mask, or add the "UI" layer to the Selector's Layer Mask.
     
  31. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    Hey Tony, thanks for the reply! The Layer mask covers all layers - UI included - but this is proven by it showing up at some points in the screen - the problem being that it is not accurate according to the location of the 2d Box Collider. Anything else you can think of? (And I apologize if this is not a problem directly related to your plugin, but it's only the plugin thats having the problem so I figured perhaps you could help)

    Thanks!
     
  32. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Ah, I missed that. When you moused over the person sprite, I thought the Selector was picking that up.

    The Selector does a raycast from the camera that's tagged 'MainCamera'. It looks like you have multiple cameras in your scene. Can you change the tags so the Selector raycasts from the correct camera to the 'N'?
     
  33. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    So the only real camera in use is currently tagged as MainCamera - perhaps this video will give more clarity on that?



    Perhaps it could be something else?
     
  34. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @brad_penbach - Aha, now I can see that "Image (1)" is a UI element. From the first video, I thought it was a sprite. The Selector ignores UI elements.

    If you want to change this behavior, you can make a subclass of Selector. Override Update(), copy the code from the original Selector's Update(), and comment out the line that checks if it's over a UI element. Like this:

    Selector2.cs
    Code (csharp):
    1. using PixelCrushers.DialogueSystem;
    2. using UnityEngine;
    3. public class Selector2 : Selector
    4. {
    5.     protected override void Update()
    6.     {
    7.         // Exit if disabled or paused:
    8.         if (!enabled || (Time.timeScale <= 0)) return;
    9.         // Exit if there's no camera:
    10.         if (UnityEngine.Camera.main == null) return;
    11.         // Exit if using mouse selection and is over a UI element:
    12.         // [DISABLED CHECK:] if ((selectAt == SelectAt.MousePosition) && (UnityEngine.EventSystems.EventSystem.current != null) && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) return;
    13.         // Raycast 2D or 3D:
    14.         switch (runRaycasts)
    15.         {
    16.             case Dimension.In2D:
    17.                 Run2DRaycast();
    18.                 break;
    19.             default:
    20.             case Dimension.In3D:
    21.                 Run3DRaycast();
    22.                 break;
    23.         }
    24.         // If the player presses the use key/button on a target:
    25.         if (IsUseButtonDown()) UseCurrentSelection();
    26.     }
    27. }
     
  35. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    I think that we're definitely getting closer - unfortunately that did not fix the problem either. Really sorry to bog you down with this so much! Anything else you can think of? Perhaps if I sent you the project it might be easier?
     
  36. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Yes, please send it to tony (at) pixelcrushers.com. I'll be happy to take a look directly.
     
  37. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    Done, thanks again! :)
     
  38. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks @brad_penbach! Since Image(1) is in a Screen Space - Overlay canvas, it's not quite the same as a regular scene object, so the Selector's raycast can't detect it. However, you can still make it react to a Dialogue System Trigger by adding a UI Button component. Configure OnClick() to call DialogueSystemTrigger.OnUse:

    upload_2019-4-30_21-1-44.png

    If you absolutely want it to go through the Selector, you can modify the Selector2 subclass's Update() method to detect UI elements using UI.GraphicRaycaster.Raycast.
     
  39. brad_penbach

    brad_penbach

    Joined:
    Aug 16, 2017
    Posts:
    12
    Brilliant fix! Thanks so much Tony :)
     
    TonyLi likes this.
  40. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Hi @TonyLi does the menu framework have a game over screen when the player dies and have an option to restart level or restart from last saved game?
     
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @dinaloraven234 - No, you'll have to add that yourself. The menu framework is general purpose. Some games don't even have a player that can die.
     
  42. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Oh okay i see but if I create one how can I use reload from last save game? Is here a script for it? Or I'll just call the load game using the events?
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    You can check if there's a saved game by calling SaveSystem.HasSavedGameInSlot(#). Then you can load it using SaveSystem.LoadFromSlot(#). Let's say you've saved the last save game in slot 1, and you saved at the beginning of the level in slot 2. Then you can connect a script like this to a UI button:

    ExampleReloadScript.cs
    Code (csharp):
    1. using UnityEngine;
    2. using PixelCrushers;
    3.  
    4. public class ExampleReloadScript : MonoBehaviour
    5. {
    6.     public void Reload() // <-- ASSIGN TO UI BUTTON.
    7.     {
    8.         if (SaveSystem.HasSavedGameInSlot(1)) SaveSystem.LoadFromSlot(1); // (last saved game)
    9.         else if (SaveSystem.HasSavedGameInSlot(2)) SaveSystem.LoadFromSlot(2); // (beginning of level)
    10.         else SaveSystem.RestartGame("First Gameplay Scene"); // (start from beginning of game)
    11.     }
    12. }
     
  44. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Dialogue System for Unity - 50% Off in May Madness Sale

    The Dialogue System for Unity is now 50% off in the May Madness Sale!
     
  45. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    So I'll just add this to the menu prefab and call this script using the events in the load from last save ui button? Anyways thanks for this. One question. For save slot 3. Will I just add this script?

    else if (SaveSystem.HasSavedGameInSlot(3)) SaveSystem.LoadFromSlot(3);
     
  46. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @dinaloraven234 - Yes, that's correct.

    You mentioned loading the last saved game. Since you're using the Menu Framework, you can use the SaveHelper component to know what the last saved game is and load it:

    Code (csharp):
    1. using UnityEngine;
    2. using PixelCrushers;
    3.  
    4. public class ExampleReloadScript : MonoBehaviour
    5. {
    6.     public void Reload() // <-- ASSIGN TO UI BUTTON.
    7.     {
    8.         var saveHelper = FindObjectOfType<PixelCrushers.DialogueSystem.MenuSystem.SaveHelper>();
    9.         if (saveHelper.HasLastSavedGame()) saveHelper.LoadLastSavedGame();
    10.         else SaveSystem.RestartGame("First Gameplay Scene"); // (start from beginning of game)
    11.     }
    12. }
     
  47. dinaloraven234

    dinaloraven234

    Joined:
    Dec 20, 2018
    Posts:
    141
    Thank you I'll use this
     
  48. Lawina

    Lawina

    Joined:
    Feb 28, 2019
    Posts:
    21
    So I want to play a talking animation (loop) when dialogue shows up until the dialogue (text) is fully shown and then the talking animation should stop (similar to Undertale). Is that possible with Dialogue System?
     
  49. CHOPJZL

    CHOPJZL

    Joined:
    Dec 5, 2016
    Posts:
    55
    Hi,Tony
    I am thinking about making small floating text. I mean small explanation text on top of some specific dialogue word, like picture below. How should I write the database to make it work?
    dialogue.jpg
     
  50. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @Lawina - Yes. This is the most common way that people set it up:

    1. Create a talking animation state and an idle animation state on the character(s) -- for example named "Talk" and "Idle".
    2. Inspect the Dialogue Manager. Set Subtitle Settings > Min Subtitle Seconds to 0 and Subtitle Chars Per Second to the same value as the typewriter effect's Characters Per Second (e.g., 50). Optionally set the Continue Button dropdown to Always.
    3. Set Camera & Cutscene Settings > Default Sequence to:
      AnimatorPlay(Talk);
      required AnimatorPlay(Idle)@{{end}}

      If you only want to do this for a specific dialogue entry node, you can set that node's Sequence field instead.
    More info:

    If that doesn't fit your needs, the typewriter effect also has OnBegin() and OnEnd() UnityEvents.

    Hi @CHOPJZL - Do you mean tooltips that appear when you hover the mouse over a word? If so, use TextMesh Pro. (The Dialogue System has native TextMesh Pro Support.) Then use <link> tags. It requires a little scripting, but this blog post has example code that will get you started. (Here's another one.)

    Here's an example of how you can put content in your dialogue database:

    1. Add <link> tags with specific names, such as "unity3d" in the example below.
    2. Then add a corresponding custom field with that link name.

    upload_2019-5-4_8-42-23.png

    3. In the method that updates the hover text (see the blog post), look up the corresponding field:

    Code (csharp):
    1. TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
    2. string fieldTitle = linkInfo.GetLinkID();
    3. DialogueEntry currentEntry = DialogueManager.currentConversationState.subtitle.dialogueEntry;
    4. string hoverText = Field.LookupValue(currentEntry.fields, fieldTitle);
     
    Lawina likes this.