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
    Good idea! I'll look into adding the same into the original script.
     
  2. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Okay, I hope I'm not getting on your nerves, but I got another question.

    Since I'm making a 2D top-down game there are some pretty specific triggers I want to use to start convesations. So I wrote my own script that just calls StartConversation() instead of using your Conversation Triggers. But now I have absolutely no idea how to change options for specific NPCs.

    Right now I need the Override Dialogue UI script for example. But my script obviously doesn't even know that the actor is that GameObject with the Override script on it, and I don't know how to tell it that.

    So - how do I do this?

    Alternatively I guess I could intercept the Conversation Trigger, but I also don't know how to do that.
    When the player comes up to the NPC I want to check some things before starting the dialogue. I only want to trigger the conversation if the player is within the collider I specified and is facing towards the NPC. Otherwise nothing should happen.
    But the way it is now the Conversation Trigger will just always trigger the conversation, no matter what. How do I restrict this?
     
  3. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Zephus - I'm happy to answer any and all questions! :)
    DialogueManager.StartConversation() has several overloads:
    • DialogueManager.StartConversation(string title, Transform actor, Transform conversant, int entryID)
    • DialogueManager.StartConversation(string title, Transform actor, Transform conversant)
    • DialogueManager.StartConversation(string title, Transform actor)
    • DialogueManager.StartConversation(string title)
    If you use an overload that specifies the actor and/or conversant, that GameObject gets associated as the primary actor and/or conversant. The primary actor and conversant are the ones that receive events such as OnConversationStart, and they're the ones that the Dialogue System checks for Override Dialogue UI components.

    If you don't specify a primary actor or conversant, or if your conversation references additional actors, the Dialogue System will use the GameObject that registered itself under that actor name using the Override Actor Name component. Otherwise, if no GameObject has used Override Actor Name, the Dialogue System will find a GameObject whose name matches the actor's name in the database.

    You can read more details in How GameObjects Are Associated With Conversations.

    It depends on how interaction works in your game. The Proximity Selector component might help. The picture below illustrates how it works. (The picture is in 3D, but Proximity Selectors works in 2D and 3D.)

    You can read an overview of Selectors here: Selectors

    An issue is that Proximity Selector doesn't check whether the player is facing the NPC. It only checks that the player is inside the collider. You could add a collider to the player that's positioned just in front of the player. Technically the player could back up really close to the NPC, but in most cases it'll just trigger when the placer approaches from the front.

    If that doesn't suit your needs, you could use a Selector. Set it to raycast from the player.

    Or you could set the Conversation Trigger to OnTriggerEnter if you want it to trigger as soon as the player enters the trigger collider.

    Or you can skip the whole Usable/Selector/Proximity Selector thing entirely, use your own interaction method, and simply call DialogueManager.StartConversation() manually when appropriate.

    If you use your own method, you can also add a Condition to your script:
    Code (csharp):
    1. public Condition condition;
    This will allow you to check other conditions such as quest states, and only start the conversation if the condition is true:
    Code (csharp):
    1. void OnTriggerEnter2D(Collider2D other) {
    2.     if (IsFacingNPC() && condition.IsTrue(other.transform)) {
    3.         DialogueManager.StartConversation("My Conv", other.transform, this.transform);
    4.     }
    5. }
     
  4. Hi. I have a question regarding the Lua implementation in Dialogue System. First of all, of course I own this asset already.
    I'm thinking about to enable my users to mod my game and I'm planning to create a couple of useful assets. My first choice would be Lua, since it's quasi industry-standard. After this thought I've looked around and checked out the current C#/Unity Lua implementations.
    Okay, after the long prologue, here is the question. Is the whole Lua Interpreter and the Extra classes inside the Dialogue System/Scripts/Lua Interpreter is\under MIT license? Can I use it in my game and/or unrelated assets? I know that the original Lua Interpreter is MIT licensed, but what about your modified (more unity-friendly) version?
    It would be nice if we wouldn't use different implementations everywhere. After all, the end users should only have one Lua Interpreter installed no matter how many AS assets were used to create the given game. :)
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @LurkingNinjaDev - Yes, the Dialogue System's modified version is MIT licensed, too. It's fine to redistribute it and use it elsewhere, as long as you don't redistribute the rest of the Dialogue System source code of course.

    (BTW, the Dialogue System uses a wrapper that isolates the actual Lua implementation. If you prefer to use NLua, you can just import the included NLua Support package. If you want to use a different Lua implementation, you just need to replace the Dialogue System's Lua.cs, LuaTableWrapper.cs, and possibly DialogueLua.cs if you want to include optimizations specific to your Lua implementation. I prefer sticking with the default Lua Interpreter because it's native C# and compatible with all platforms.)
     
  6. Of course, I won't include anything from the Dialogue System, of course. :) Thank you for the advice as well!
     
    TonyLi likes this.
  7. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Thank you for the detailed answer. I think I get it now, but I may need some time to wrap my head around the entire structure of the asset. Especially the Lua thing with items, quests and such is a bit much for me at the moment, but I hope I'll get it some day.

    If you don't mind, more questions (hooray):
    1) I'm really not sure what locations are supposed to do. Items I get, since I can use them with the quest system, but what exactly would I be using the Locations for?

    2) Is there any functionality I absolutely can't access if I ignore Lua? I've just read the documentation on working with quests in scripts and it uses Lua from beginning to end, but then it mentions the QuestLog class that seems to do everything just the same.
    I'd really prefer being able to just write my own scripts and directly call DialogueManager functions from there to be honest (as well thought out as your scripts and Lua implementation are ;)).

    If I don't use Lua, how would I, for example, make a dialogue check a variable in my GameManager script, that stores all the information about the game state in static variables?

    3) Any easy way to make an actor choose a random node? I thought if I just created two child nodes with the same priority it would choose randomly, but it seems to always choose the first one.

    4) Can I safely ignore the localization part for now and easily add it in later or should I build my game with that in mind? I'm not sure I'll need different languages, but if I suddenly do and had to change the entire project, that would really suck.

    5) I'm using EasySave. If I call
    Code (CSharp):
    1. ES2.Save(PersistentDataManager.GetSaveData(), "myFile.txt?tag=dialogueSystem");
    there's absolutely nothing else I need to worry about regarding everything in my Dialogue Database (conversations, items, quests, variables etc.)? Everything the asset needs is then saved within the one 'dialogueSystem' tag?
     
  8. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Zephus,
    Whatever you want, or nothing at all. When designing the Dialogue System, I wanted to take advantage of a proven data structure that had already worked well for lots of successful games. So the Dialogue System uses the same data structure as the professional dialogue authoring application Chat Mapper. Chat Mapper has a table for Locations, so the Dialogue System does, too. The Dialogue System doesn't do anything special with Locations, though, so it's free for you to use or ignore as you see fit.

    Not at all. You can access all built-in functionality using point-and-click dropdowns menus:


    You don't have to type a single character of Lua. If I'd left it at that, and hid the underlying Lua, the Dialogue System would still be very powerful, with the ability to check conditions based on variable values, quest states, SimStatus, Actor and Location fields, and more. (And of course set those variable values, quest states, etc.)

    But, by exposing Lua, you can hook in your own C# code, too. This is how the third party support packages work. They register C# functions with Lua. With the S-Inventory integration, for example, you can conditionally branch conversations based on inventory items (using the GetItemAmount() Lua function) or give items to the player during conversations (using the AddItem() function). But directly using Lua like this is entirely optional.

    In this case, my preference would be to use Lua and register a function that returns the value of a GameManager variable.

    But that's not the only way to do it. You can do it entirely in your own C# script and with the dropdown menu shown above. Here's one way to accomplish this:
    1. Define a matching variable name in your dialogue database.
    2. Use the dropdown menu to check a variable condition.
    3. In your C# script, keep the dialogue database version of the variable synchronized with your GameManager version. For example, something like:
    Code (csharp):
    1. private static int s_gold; // The player's gold.
    2.  
    3. public static int gold {
    4.     get {
    5.         return s_gold;
    6.     }
    7.     set {
    8.         s_gold = value;
    9.         DialogueLua.SetVariable("gold", value); // Set the dialogue database variable.
    10.     }
    11. }
    If you don't want to keep it synchronized like this, you can always synchronize all variables at the beginning of the conversation by adding an OnConversationStart method to a script on your Dialogue Manager. In that method, use DialogueLua.SetVariable() to set all the variables you want to sync to the dialogue database.

    Here are two posts with techniques for random nodes:
    Another way to do random text is to use the RandomElement() Lua function in your Dialogue Text. It's Lua, but it's just a little bit. ;) RandomElement() is a quick way to add variety to a line all in one node, such as:
    • Dialogue Text: [lua( RandomElement("Hi! | Hello. | W'zup? | Yo.") )]

    You can safely ignore localization for now. The only exception is if you're using "entrytag" in your sequences. This is the only case where you need to plan ahead by using "entrytaglocal" in your sequences instead. People usually only use entrytag in the Dialogue Manager's Default Sequence. In this case, since it's just one instance, it's not a big deal whether to handle it now or later.

    Yes. And when you load a game, call PersistentDataManager.ApplySaveData() to apply it back into the Dialogue System.
     
    Last edited: Mar 24, 2017
  9. Riff-Rex

    Riff-Rex

    Joined:
    Mar 14, 2014
    Posts:
    19
    Hi Tony,

    I'm having trouble with something that I feel is probably simple and I'm missing something obvious but basically:

    I want to tie a static bool or int in my C# script to a Variable in the Dialogue manager. Can't I just say: DialogueLua.SetVariable("Score", score) (with "Score" being the Dialogue Manager Variable name and score being the bool or int in the script) and then set the conversation conditions to have the effect I want? Condition: Variable["Score"] == true; (if it's a bool), Variable["Score"] > 13; if it's a number/int.

    I've tried putting the C# code in Update() and OnConversationStart() but it doesn't seem to be affecting the Dialogue Manager's associated Variables.

    side note: I've been able to successfully use GetVariable(). It's just SetVariable() I seem to be doing something wrong.

    Thanks!
     
  10. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Riff-Rex - That should work. Here's an example scene that uses SetVariable():
    SetVariableExample_2017-03-25.unitypackage

    In the example scene, I added the script below to one of the GameObjects that receives the script messages.
    Code (csharp):
    1. using UnityEngine;
    2. using PixelCrushers.DialogueSystem;
    3.  
    4. public class SetVariableOnConversationStart : MonoBehaviour {
    5.  
    6.     public int score;
    7.  
    8.     void OnConversationStart(Transform actor) {
    9.         Debug.Log("OnConversationStart: Setting Score to " + score);
    10.         DialogueLua.SetVariable("Score", score);
    11.     }
    12. }
    The issue may be that Conversation Evaluate Conditions One Extra Level Ahead. If you're setting Score in OnConversationStart and checking Score at the very beginning of the conversation (i.e., in nodes that directly link from START), the check will occur before OnConversationStart runs. In the example scene, I added an empty node from START to delay evaluation.
     
  11. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Thank you again. I think I got all of that now.

    I've encountered a new problem though. It just never stops. :(
    You remember when I had the problem with the Unity UI that un-focused the continue button when I clicked somewhere, right? You told me to use the Key Trigger component, so I did, and it worked perfectly. And then I came to a response menu.

    I have absolutely no idea how to navigate the response menu without Auto Focus. I can't enable Auto Focus, because then the Continue button will be clicked twice (once because it's focused, once because of the Key Trigger). And even if I did a mouse click somewhere on the screen will deselect the reponses.

    So how do I navigate the responses with my gamepad or keyboard only without losing focus?
     
  12. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    First of all, thank you so much for this asset, it's helping me so much! Now, I'd like to ask for help about a couple of things. Also my English sucks, so yeah.

    Okay so, I make a conversation between two actors. The moment the conversation starts, I want the player to stop being able to move, so I use the sequence SetEnabled(). Obviously, when the conversation ends I want the player to be able to move again, so I make an empty node with the sequence I used before. Good, the conversation is over and I can move again! The problem now is that, for some reason, when I try to speak with other NPCs conversations won't start. I was able "fix" this by changing the actor that is speaking. Before it was: NPC talking to Player. After changing: Player talking to NPC. Which means the player has to choose an answer now. What i'm trying to say is that having the player answer to an NPC "fixes" the problem with the other NPCs but it would require to end every conversation with an answer and that's pretty ugly if ask me.


    I have another question.
    How do I prevent the player to press or click to go through a conversation before an NPC animation ends?


    I'm sorry if i'm bothering you! Also thank you!
     
  13. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Zephus - I've already added this feature to Unity UI Dialogue UI for the next release. You can download an advance copy here:

    UnityUISupport_2017-03-25a.unitypackage
    (EDIT: ^updated)

    This package also includes the updated typewriter effect with the enhancements you suggested earlier. (And thanks again for those ideas!)

    If Auto Focus is ticked, it will now automatically check every 0.5 seconds to make sure a response is focused. (Or, if a subtitle is active, it will make sure the continue button is focused.) You can change the frequency by editing the new Auto Focus Check Frequency value that's below Auto Focus. If it's zero, the dialogue UI will only check once at the beginning when it shows the subtitle/response menu.

    Hi @Sigma266 - Better than using the SetEnabled() sequencer command, I recommend adding a Set Component Enabled On Dialogue Event component to the player. See the Feature Demo scene for an example. Briefly, set the Trigger to OnConversation. Add an element to On Start, assign your controller script, and set the State to False. Then add an element to On End, assign the same controller script, and set the State to True.

    If you're using a continue button and you want to disable the continue button during the animation, use a sequence like this:
    Code (sequencer):
    1. SetContinueMode(false);
    2. AnimatorPlayWait(myAnimation)->Message(Done);
    3. SetContinueMode(true)@Message(Done)
    This uses the SetContinueMode() sequencer command at the "->Message" and "@Message" syntax.
     
    Last edited: Mar 26, 2017
  14. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Thank you, I'll try the new version. I actually fixed the problem in the meantime by using this script in the background:
    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (EventSystem.current.currentSelectedGameObject == null)
    4.             EventSystem.current.SetSelectedGameObject(lastSelected);
    5.         else
    6.             lastSelected = EventSystem.current.currentSelectedGameObject;
    7.     }
    From what your saying your new version seems to do pretty much the same, so I'll try using that.

    edit:
    I imported the package, but the first thing that happens is that I get a NullReferenceExpception in line 474 of the UnityUIResponseMenuControls.cs:
    Code (CSharp):
    1.     if (currentSelection == buttons[i].gameObject) return;
    Not sure what's causing it yet.

    edit2:
    Stupid mistake - I had an empty field in the button array of the dialogue UI. Working perfectly now. :)

    edit3:
    Aaand for the final edit - might I suggest the same functionality my script has? It saves the last selected object and sets the focus back to that. The way you implemented it the focus always snaps back to the first option.

    By the way - is there an option to prevent the answer I've chosen in a response menu from being shown again after that?
    For example I have the responses "Yes" and "No". "No" is supposed to just end the conversation and Yes leads to another node. But when I choose one of them it shows "Yes" or "No" again before moving on.
     
    Last edited: Mar 25, 2017
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    I'll add a null check to handle this more gracefully.

    I was just getting online to post about that. I'll do that, and also add an option to not steal focus if a different panel has focus. Right now, the response menu steals focus back. This is by design, in case whatever non-menu control that's currently focused doesn't provide a way to navigate back to the menu. But I can imagine cases where the designer might want to let the player navigate around different panels while the menu is open.

    Typically you add a condition to the node. You can check a variable or use SimStatus. But SimStatus might be overkill if you only need it in a few places.

    The Dialogue Manager does have an option in Display Settings > Input Settings > Em Tag For Old Responses, but this simply wraps already-chosen responses in an [em#] tag. It doesn't actually remove it from the menu.
     
  16. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Oh, I think you misunderstood. I want the text of the response I've chosen to not be displayed at all (because it's enough that it's already there in the response menu).

    Here's a screenshot of what I mean:
     
  17. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    Hi @Sigma266 - Better than using the SetEnabled() sequencer command, I recommend adding a Set Component Enabled On Dialogue Event component to the player. See the Feature Demo scene for an example. Briefly, set the Trigger to OnConversation. Add an element to On Start, assign your controller script, and set the State to False. Then add an element to On End, assign the same controller script, and set the State to True.


    If you're using a continue button and you want to disable the continue button during the animation, use a sequence like this:
    Code (sequencer):
    1. SetContinueMode(false);
    2. AnimatorPlayWait(myAnimation)->Message(Done);
    3. SetContinueMode(true)@Message(Done)
    This uses the SetContinueMode() sequencer command at the "->Message" and "@Message" syntax.[/QUOTE]

    Thanks for answering! I'm still have some problems though.

    The Set Component Enabled on Dialogue Event doesn't work at all. I put my player inside one of the elements and set it to false but it keeps moving. I also tried the Set Enabled on Dialogue Event, the one that uses scripts components, but no luck.

    -------

    And about the animations... it works, but I'd like to know if there's a way to make the animation loop? For example, i'm trying to make an NPC walk for 2 seconds to get to a certain point on the map. The animation is simply the NPC making 2 steps forward, but the AnimatorPlayWait() sequence doesn't seem to allow more than one animation at a time, which results in the continue button being released way too soon. Any way to fix this? Thank you again.



    OH! I was able to fix the problem with Set Component Enabled on Dialogue, but when I talk to an NPC my character keeps sliding until the conversation is over. Though I think that has to do with my script and the RigidBody. :l
     
    Last edited: Mar 26, 2017
  18. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    I think I understand now. What about unticking the Dialogue Manager's Display Settings > Subtitle Settings > Show PC Subtitles During Line checkbox?

    Alternatively, if you want to show the PC subtitle most of the time, you can set the Sequence of specific responses to: Continue() to bypass showing the subtitle.

    This is very dependent on the controller/script you're using. Every controller works a little differently. It may be that the character's Animator has a parameter such as "speed" that you must set to 0 to stop the character. To do this, add a Start Sequence On Dialogue Event component that sets the parameter. For example:



    Note that Set Component Enabled On Dialogue Event and Start Sequence On Dialogue Event are helper components, not core Dialogue System components. You don't have to use them. If you prefer, you can instead write a script with OnConversationStart and OnConversationEnd methods that stop and start your character. The Dialogue System provides the optional helper components so you can choose to use them if you don't want to write any scripts.

    Short answer: Yes. Use AnimatorPlay(). This kicks off the animation state without waiting, and lets it run until you stop it.
    Code (sequencer):
    1. SetContinueMode(false);
    2. AnimatorPlay(walk);
    3. SetContinueMode(true)@2

    If your sequence is more complicated, I can provide 3 suggestions. (Take your pick.)

    Suggestion 1: Use a sequence of sequencer commands:
    Code (sequencer):
    1. SetContinueMode(false);
    2. AnimatorPlay(walk);
    3. LookAt(Door,,1)@3;
    4. AnimatorPlay(wiggle_doorknob)@5;
    5. AnimatorPlayWait(knock)@7->Message(Done);
    6. SetContinueMode(true)@Message(Done)
    This may look complicated, and in one sense it is. But I was able to type it in less than 10 seconds, which is faster than working in an interactive sequencer such as SLATE or Cinema Director. The sequence does this:

    Time Action
    00:00 Hide continue button
    00:00 Play "walk" state
    00:03 Rotate to face Door over 1 second
    00:05 Play "wiggle_doorknob" state
    00:07 Play "knock" state. When done, send sequencer message "Done"
    --:-- When sequencer message "Done" is sent, show continue button


    Suggestion 2: Use an interactive sequencer. For very long, complicated sequences, you may find this easier. The Dialogue System has built-in support for SLATE, Cinema Director, uSequencer, and others. You can mix and match interactive sequences with text-based sequencer commands.


    Suggestion 3: Write a custom sequencer command to do the entire sequence.
     
  19. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    I updated the UI scripts:

    UnityUISupport_2017-03-25a.unitypackage

    Changes:
    • Gracefully handles if an element of Buttons list is unassigned.
    • Refocuses last (most recent) response instead of first response in list.
    • Added Allow Steal Focus checkbox. Untick to allow non-dialogue UI controls to retain focus during conversations.
    • Implemented same behavior for alerts and quest log window.
     
  20. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    Thanks a lot for the support! I really appreciated it :)
     
  21. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Happy to help!
     
  22. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    I'll try the new package when I get home, thanks. Also the Continue() Sequence works just fine. Didn't know about that one.

    I'm not sure if I'm the only one but as far as I know the majority of games that have response menus and dialogues between the player and NPCs don't show the player's lines once more after choosing them.
    They just move on to the next NPC answer. So I was pretty confused that there's not a standard option for that. The only games I even know that do the 'player says the chosen line' are big Bioware RPGs and The Witcher.

    Not sure how much work that would be, but I feel like an option for "Hide PC dialogue after response" or something like that would be a good idea. I mean - if I wanted to show some text afterwards I could just create another Player node anyway.
     
  23. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    That's the kind of game the Dialogue System came out of -- an unfortunately cancelled planet-hopping sci-fi with fully voiced lines. :) Side note: We used the excellent but pricey and relatively time-consuming FaceFX at the time. But since the advent of Asset Store products like SALSA and LipSync, voiceover is now within the reach of even lone indie devs as long as you can find voice actors to record the audio.

    There's already the built-in option Show PC Subtitles During Line that you can untick. Its wording is kind of backward from "Hide PC subtitle (dialogue) after response", but the intent is the same. I'll also add an option that shows subtitles except if it was from a response menu choice.
     
    Last edited: Mar 26, 2017
  24. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    It's always sad to hear when projects like this get cancelled. I have to say that it really shows. I'd nearly say that there's too much Dialogue System does - it gets really overwhelming for beginner game devs like me.

    Basically I was just looking for a 'message box' system for my NPCs and then I saw Dialogue System in a sale with 300+ 5 star reviews, so I bought it. I didn't even realize it did quests, sequences, barks, saving and localization at first. But now that I've seen what it can do I'm trying to integrate as much as possible into my game, so I can make full use of it.
    Would be a shame if I just used it to hold my dialogue and used nothing but 'StartConversation()' all the time.

    I know that option is there. But what it does is hide all PC subtitles, so I only see the NPC ones, right? I'm not sure where that would come in handy to be honest. Then your character couldn't say anything anymore.
    Wouldn't you normally want your player character to talk with the NPCs, then they ask you something, you choose an answer, and they react to that answer?

    That's kind of my thinking, since most games I play do it like that. So it's good to see that you're adding the 'show subtitle except from a response menu' option. It would get pretty tedious having to add Continue() to every single response menu choice. Thank you!
     
  25. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    This is the most common criticism of the Dialogue System, and I think it's fair. It's a difficult balance. I consciously restrict the design so it does everything required to properly support AAA-caliber dialogue without extra stuff. It just turns out that dialogue is subtly more complicated than it seems at first blush.

    I don't think there'd be anything wrong with that. Plenty of games just use it like that. Like Unity itself, you don't have to use every single feature in every game. Then again, there are games that use every single feature and then push it further, which is why the Dialogue System provides lots of customization hooks.

    The Feature Demo uses this option. It only hides the PC subtitle, which is the text that's shown after the player selects a response from the response menu. The player still gets the response menu.
     
  26. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    You're right, sorry. But that completely prevents me from having text boxes where the Player says something (without a response menu), right? That's why I was looking for the 'show player subtitles, but don't show the one that comes with the response menu' feature.
     
  27. alexhapki

    alexhapki

    Joined:
    May 8, 2015
    Posts:
    32
    Hi Tony!
    I have just wanted to let you know we launched crowdfunding for the videogame we made with Unity and Dialogue System. It is a beta version, just part 1, 10-15hrs, we want to release it so we start having feedback from people.
    Here is the link;
    https://www.kickstarter.com/projects/legendsofeternalia/the-essence-reaper-ritual

    I have to say your Dialogue Manager is the core of our dialogues, quests and saving data. It is very easy to save and manage data with your application. Thank you very much.
    Alex.
     
  28. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    I'll have this change submitted to the Asset Store by mid-week.

    Awesome! Best of luck on your Kickstarter campaign!
     
  29. Zephus

    Zephus

    Joined:
    May 25, 2015
    Posts:
    356
    Your support is really bar none @TonyLi. Others don't update their assets in months and you just implement suggestions in a few hours - can't praise you enough. Thank you!

    You may want to read up on some Kickstarter Best Practices. Not to be mean - but there's quite a few things that would prevent me from backing your project.
    I know the funding goal is really low, but here are just a few suggestions for the video, since that's the only thing most people will be seeing:
    • Faaaaaar too long. You want it to be more like a trailer and not much longer than 2-3 minutes. You can have additional videos or gifs in the project description. If there's not even voice-over it's pretty hard to pay attention for 11 minutes.
    • The framerate of the video makes it seem like the game runs at 5 FPS.
    • What's with the glitching at 1:44? Don't leave stuff like that in
    • Use a better Font (not only in the video, but also in the game). Arial or whatever that is pretty much always looks like something was made in Paint. There's a lot of free fantasy fonts out there - just read up on their license.
    There's a lot of great Kickstarter resources out there. This is probably the most recommended one:
    https://stonemaiergames.com/kickstarter/

    Not trying to discourage you, just some things that I noticed. Still - best of luck for your campaign. :)
    And remember: Most people's attention span is like 5-10 seconds long. You need to engage people quickly, or someone else will do it. ;)
     
    hopeful, alexhapki and TonyLi like this.
  30. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    Heeey, i'm back!

    So, with your help I was able to let animations run before the player could go on with the conversation, and it works great!
    But I want the game to playable with a keyboard, not the mouse. So I followed the guide to do it. The continue button now works with a key, but the sequences I used to prevent the button from being pressed don't work anymore. (By the way, SetContinueMode() was the sequence) Is there something that lets the player press the key only when the text is fully displayed? Same for animations. Sorry, I know this question is pretty much the same as the one I asked before, but for some reason these sequences don't work anymore!

    I have another question. So, when I enter in a trigger zone an NPC starts talking to me, so my player stops because it has attached the SetComponentEnabled thing or the StartSequenceOnblabla thing, both set on false. But I want the player to press a key when he enters the trigger zone to start a conversation, so I made a little script. Now the problem is that the two components I used to stop the player from moving are being completely ignored, that I can move freely while talking. When I use On Trigger Enter, everything works fine, but when I use On Use, which I need for the script, that happens.

    Thank you for the help.
     
  31. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Sigma266 - The Unity UI Typewriter Effect has events for OnBegin() and OnEnd(). You can use them to deactivate the continue button GameObject or set its Button component's Interactable checkbox:


    The Conversation Trigger needs to know which GameObject is the actor (i.e., player). You can either assign the player GameObject to the Actor field or pass it in OnUse such as (for example):
    Code (csharp):
    1. npc.conversationTrigger.OnUse(player.transform);
    BTW, you can probably use Proximity Selector to do the same thing as your script:

    The Topdown Demo inside the Examples/Feature Demo/Topdown Demo folder demonstrates Proximity Selector.
     
  32. alexhapki

    alexhapki

    Joined:
    May 8, 2015
    Posts:
    32
    Hi Zephus!
    Thank you very much for the comments. I think you are right about making a smaller video. I will work on that tomorrow. I am not sure If it can be changed now that it has been launched.
    FPS; it runs from 100 to 450 FPS, video capture really make it look like lower. I can perhaps show the stats briefly in the video to show FPS.
    Hey, I appreciate the comments and suggestions to improve my stuff, any thoughts like that are more than welcome.
    Thank you again,
    Alex.
     
  33. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    I'm really sorry but they're not working at all. Let me explain...

    First of all, the Unity UI Typewriter Effect doesn't work. My Subtitle Line object only recognizes the normal Typewriter effect, but that prevents me from deactivating the continue button and reactivating it since the Unity UI Typewriter Effect is the one that can do that. (I don't think this matters but i'm using the JRPG2 Dialogue UI, that I changed a little bit)

    Then there's this other problem I have. The Proximity Selector component doesn't work, but I thought I could try the script you've shown me. That doesn't work either, BUT only because when i'm writing code:
    1. npc.conversationTrigger.OnUse(player.transform);

    the part npc is considered wrong and I don't know what to do with it. Again, thank you so much for everything you do.
     
  34. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @Sigma266 - Here's an example scene that uses Proximity Selector and includes a script for the legacy GUI typewriter effect: ProximitySelectorExample_2017-03-27.unitypackage

    The script assumes you only want to use a continue button for the NPC. If you also want to use it for the Player, let me know and I'll post a modified version. I'm assuming that the Player will always "talk" through the response menu.

    Here's a copy of the script in case you don't want to download the example:

    HideContinueButtonDuringTypewriter.cs
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace PixelCrushers.DialogueSystem.UnityGUI
    5. {
    6.  
    7.     [RequireComponent(typeof(UnityDialogueUI))]
    8.     public class HideContinueButtonDuringTypewriter : MonoBehaviour
    9.     {
    10.  
    11.         private UnityDialogueUI dialogueUI;
    12.         private TypewriterEffect typewriter;
    13.  
    14.         void Awake()
    15.         {
    16.             dialogueUI = GetComponent<UnityDialogueUI>();
    17.             if (dialogueUI == null) Debug.LogError("No UnityDialogueUI found. HideContinueButtonDuringTypewriter will not work.");
    18.             typewriter = dialogueUI.dialogue.npcSubtitle.line.GetComponent<TypewriterEffect>();
    19.             if (typewriter == null) Debug.LogError("No TypewriterEffect found. HideContinueButtonDuringTypewriter will not work.");
    20.         }
    21.  
    22.         void OnConversationLine(Subtitle subtitle)
    23.         {
    24.             StopAllCoroutines();
    25.             if (subtitle.speakerInfo.characterType == CharacterType.NPC)
    26.             {
    27.                 StartCoroutine(HideContinueButtonWhileTyping());
    28.             }
    29.         }
    30.  
    31.         void OnConversationEnd(Transform actor)
    32.         {
    33.             StopAllCoroutines(); // Safeguard to stop coroutine just in case.
    34.         }
    35.  
    36.         IEnumerator HideContinueButtonWhileTyping()
    37.         {
    38.             // Wait 1 frame for dialogue UI to set up line:
    39.             yield return null;
    40.             // Hide the continue button:
    41.             dialogueUI.dialogue.npcSubtitle.HideContinueButton();
    42.             // Wait until the typewriter is done playing:
    43.             while (typewriter.IsPlaying)
    44.             {
    45.                 yield return null;
    46.             }
    47.             // Finally, show the continue button:
    48.             dialogueUI.dialogue.npcSubtitle.ShowContinueButton();
    49.         }
    50.  
    51.     }
    52. }
     
  35. katie-muller

    katie-muller

    Joined:
    Feb 18, 2014
    Posts:
    18
    EDIT: So I originally had a question here about canvases, but I decided to go with a different approach that worked better for my game. So nevermind my old question =)

    But, I do have a different question, if you don't mind! I'm trying to make a tutorial for my game, where my character points out different parts of my game's UI and explains them. To do this, I'm using a translucent Image (in Unity's UI) that overlays the part of the UI I the player to focus on and blinks between no opacity and full. I call them Highlighters in the inspector. Pretty basic stuff, but gets the job done!

    What I'd like to do is turn off the Highlighter (after she is finished explaining) and activate another Highlighter. I tried writing the Lua code myself like so, but it was giving me errors with the way I wrote it:

    Code (CSharp):
    1. public bool SetGameObjectActive(string gameObjectName, bool setTo){
    2.         return GameObject.Find (gameObjectName).SetActive(setTo);
    3.     }
    So after researching, I discovered there is already an "SetActive()" function in the Dialogue System, but I can't seem to get it to work. Here is what I wrote in the Script field of my dialogue entry:

    Code (CSharp):
    1. SetActive(Interaction Panel Highlight, false)
    "Interaction Panel Highlight" is the exact name of my object in my inspector. Where am I going wrong? Thanks for all the help, as always!
     
    Last edited: Mar 28, 2017
  36. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @katie-muller - Just a side note then: Should you need to use different canvases in the future, you can use an Override Dialogue UI component.

    Put SetActive() in the Sequence field. This is a sequencer command. The Dialogue System has two places where you can enter two different types of commands: The Script field for Lua code, and the Sequence field for sequencer commands. Conceptually, Lua code is for manipulating data (such as setting variables), while sequences are for changing the user experience (such as showing Highlighters, playing animation, etc.), although their roles can overlap. The Dialogue System comes with a big library of useful sequencer commands, and you can write your own, too, similarly to how you can add your own Lua functions.

    The conversation won't progress to the next step (i.e., the next subtitle or the response menu) until the Sequence is done. Since the SetActive() sequencer command finishes immediately, if you want to delay before progressing also use the Delay() command, such as:
    Code (sequencer):
    1. SetActive(Interaction Panel Highlight, false);
    2. Delay({{end}})
    The {{end}} keyword is a special value that's based on the length of the dialogue text.
     
    katie-muller likes this.
  37. katie-muller

    katie-muller

    Joined:
    Feb 18, 2014
    Posts:
    18
    Thank you, that makes sense! Sequencers seem pretty useful! Thanks for linking the library as well, I'm gonna start using these more often =)
     
    TonyLi likes this.
  38. katie-muller

    katie-muller

    Joined:
    Feb 18, 2014
    Posts:
    18
    I just stumbled across another issue and I've spent some time trying different things, but I can't seem to figure out what's happening.:( After my tutorial dialogue is finished, it seems like my gameplay dialogue doesn't want to display.

    I'm calling my gameplay dialogue manually in my Game Manager script when it's each characters turn (their bars light up when it's their turn). I attached a GIF of normal gameplay for reference.

    Normal_Gameplay.gif

    In my tutorial scene, I have everything set up the same way, except for two things: My Game Manager script is turned off in the inspector before the scene plays (to prevent a turn from starting until the tutorial dialogue is finished). I have a "Tutorial Manager" gameObject set up so it plays the "tutorial dialogue" on start, and when it's finished, it enables the Game Manager script to initiate normal gameplay. (I also tried Set Component Enabled and had the same result).

    tutorial manager.PNG

    For some reason, my Game Manager component never enables, resulting in this happening. Which is weird because the alien shouldn't move unless the Game Manager script is enabled (their behavior is based off of it). This is what happens after her tutorial dialogue:

    Tutorial_Issue_Gameplay.gif

    I placed a break point where my gameplay conversation was being called, and it was actually being hit despite the script being disabled?o_O I'm not so sure what's happening.

    breakpoint_image.PNG
     
  39. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @katie-muller - Try assigning the Tutorial Manager GameObject itself to its Conversation Trigger's Conversant property. This will allow it to receive the OnConversationEnd event. (When a Conversation Trigger is set to OnStart, it uses the GameObjects specified in its Actor and Conversant fields. These GameObjects, as well as the Dialogue Manager itself, receive events such as OnConversationStart and OnConversationEnd.)

    You can also put a Conversation Logger (Component > Dialogue System > Miscellaneous > Conversation Logger) on the Tutorial Manager GameObject. When the conversation finishes, you should see a line like:

    Tutorial Manager: Ending conversation with Kyla


    When a script is disabled, this only means that Unity won't automatically run its Start and Update methods. If another script calls one of its methods directly, that method will still run. I don't know if that's the issue or not; just a thought.
     
    katie-muller likes this.
  40. katie-muller

    katie-muller

    Joined:
    Feb 18, 2014
    Posts:
    18
    So I tried setting the Tutorial Manager to the Conversant property, and the Game Manager now enables after the conversation is over! The Logger also shows that the tutorial conversation ends successfully. We're one step closer.

    However, the gameplay dialogue still doesn't appear =( I tried setting "Allow Simultaneous Conversations" in the Dialogue Manager to be true, just in case maybe something in the dialogue was lingering and wasn't letting the other one start. But that didnt help :(
     
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Petit a petit! :)

    Here's an example scene: TutorialThenConversationExample_2017-03-28.unitypackage

    This is the GameObject hierarchy and Tutorial Manager GameObject:


    • It has a Conversation Trigger that runs OnStart.
    • It has an Override Dialogue UI that uses a different dialogue UI for the tutorial.
    • When done, the Player and Conversant (the Tutorial Manager GameObject) receive OnConversationEnd. The Tutorial Manager's Set Enabled On Dialogue Event enable the Game Manager GameObject's GameManager script.
    This is the Game Manager:


    The GameManager script starts disabled. The script itself just runs a UnityEvent on start:
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class GameManager : MonoBehaviour {
    4.  
    5.     public UnityEngine.Events.UnityEvent onStart;
    6.  
    7.     void Start() {
    8.         onStart.Invoke();
    9.     }
    10. }
    I configured the event to call the Conversation Trigger's OnUse() method, which starts a regular conversation.

    Your Start() method of course could do something different. This was just a simple way to test the conversation trigger.
     
  42. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    I had it working for a long time in my project up until now but using "FSMEvent" to send events to Playmaker has stopped working and I'm getting this message-

    Dialogue System: Can't find any built-in sequencer command named FSMEvent() or a sequencer command component named SequencerCommandFSMEvent()

    I haven't upgraded Unity, Dialog System or Playmaker- I'm using Dialog System 1.6.6.5- I did reorganize my asset folder recently- could that have broken the functionality? Thanks.
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Hi @mdotstrange - Sounds like your project is missing the file SequencerCommandFSMEvent.cs. It's possible that the file got lost in the reorganization. Can you try reimporting the PlayMaker Support package from the Dialogue System's Third Party Support folder?
     
  44. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Thank you for the quick reply-

    I just checked and it seems that file is in my project


    When I first had the problem I tried re-importing the package and it says all files are already installed- You can see the file path in the image- would being too deep in a file path and/or having it be in the Plugins folder be causing an issue? Thank you.
     
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Try moving it out of Plugins. (Sorry, I know you just tidied everything up in your project.) The sequencer uses reflection to find new sequencer commands that aren't built in, and it may have trouble reaching into Plugins for that. I can look into adding support for that in a future release.
     
  46. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    That fixed it :) Thank you so much for the quick and excellent support.
     
  47. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Glad that worked! Version 1.6.9 just went through QA, but before publishing it later today I should have time to work in a fix to support custom sequencer commands in the Plugins folder so you'll be able to move it back in if you want.
     
  48. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    Dialogue System for Unity 1.6.9 Released!

    Version 1.6.9 is now available on the Pixel Crushers customer download site. (PM me your Asset Store invoice number if you need access.) It should be available on the Asset Store in 5-7 days.


    Version 1.6.9
    Core
    • Dialogue Editor:
      • Added: Fast Undo for Large Databases checkbox.
      • Added: Separate template menu options Apply Template To Assets, Update Template From Assets.
    • Added: Dialogue Manager Subtitle Settings option: Skip PC Subtitle After Response Menu.
    • Added: Dialogue Manager Alert Settings Chars Per Second, Min Alert Seconds
    • Added: New entrytag option "Conversation ID_Actor Name_Entry ID".
    • Added: PersistentDataManager/GameSaver/Dialogue Manager option to include location data in save data.
    • Added: DialogueLua.GetConversationField(), MarkDialogueEntryUntouched().
    • Changed: Dialogue Manager makes itself a root GameObject before calling DontDestroyOnLoad.
    • Fixed: Sequencer could report NullReferenceException in some cases if the scene had no MainCamera and no sequencer camera.
    • Fixed: Dialogue Manager now receives OnConversationEnd message when conversation is cancelled.
    • Fixed: Barks were running the Lua Script field twice.
    • Fixed: Sequencer wasn't recognizing custom sequencer commands in Plugins folder.
    • CSV import/export: Added more robust recovery when encountering invalid links.
    • Unity UI:
      • Improved: Localization of quest group names.
      • Typewriter Effect: Added several enhancements such as ability to skip audio on specific characters.
    Third Party Support
    • Adventure Creator: Updated for Adventure Creator 1.56b+.
    • PlayMaker: Get/Set Variable/LuaField actions can now accept int values.
    • Realistic FPS Prefab: Added Control Rotation checkbox in FollowFPSPlayer.
    • TextMesh Pro: Added localization support for arbitrary TextMesh Pro components.
     
  49. takapi

    takapi

    Joined:
    Jun 8, 2013
    Posts:
    79
  50. Sigma266

    Sigma266

    Joined:
    Mar 25, 2017
    Posts:
    99
    Omg, thank you so much for this!! It works perfectly now! Though I'd like to know why it only works with the "Usable" component attached.