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

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Do this system support the built in speech recognition in Unity?
     
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @virror - Unity doesn't have built-in speech recognition (yet!). There is, however, a Speech-to-Text package on the Asset Store that acts as a wrapper for several third party solutions. If this is what you're talking about, you could use it similarly to these instructions on Using Wit.ai speech recognition in the Dialogue System.
     
  3. Hormic

    Hormic

    Joined:
    Aug 12, 2014
    Posts:
    251
    Hi TonyLi,

    I have a little problem with RT-Voice in combination with Dialoge System and Salsa.
    Here is my corespondence with Stefan the RT-Voice Developer and he mentioned that this is maybe a problem in DS -> https://forum.unity3d.com/threads/r...to-speech-solution.340046/page-7#post-2910537

    What do you think?

    and btw i have a warning with RFPS:
    is this of any relevance?
     
  4. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    I was thinking about the UnityEngine.Windows.Speech, which is a form of speech recognition.
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    The Dialogue System will tell RT-Voice to choose a voice based on the Dialogue System's "RT Voice Actor" component's configuration:


    Add 2 elements to the Voice Preferences list. Configure them similar to this:
    • Element 0
      • Language: de
      • Name: Hedda
    • Element 1
      • Language: en
      • Name: Zira
    Then set the Dialogue System's localization language to "de" or "en" to match one of the elements above.(Also make sure the Gender and Min/Max Age fields are configured so the voice will match the actor's needs.)

    You can set this through the Inspector on the Dialogue Manager by setting Display Settings > Localization Settings > Language. Or through code (or equivalent PlayMaker action) like this:
    Code (csharp):
    1. DialogueManager.SetLanguage("en");
    If you've ticked Display Settings > Localization Settings > Use System Language, it will set the Language field to whatever .NET determines as the player's current system language code. In this case you'll want to make sure you have a matching element in the RT Voice Actor component.

    If the info above doesn't help, please feel free to send an example project to tony (at) pixelcrushers.com and let me know what version of Unity to use. I'll be happy to take a look.

    No relevance. It's a harmless warning right now, but the next release of the RFPS Support package will take care of it.

    Hi @virror - Yes, you can use that similarly to the Wit.ai example I linked to previously. Please note that it will only work for Windows builds, not for any other platforms. The Dialogue System doesn't include a specific integration because it depends on your game design. In one game, you might want the player to specify a response number, such as "Choose response number 2". In another game, you might want to listen to natural language and try to match keywords to responses as in the Wit.ai example. If you have any specific questions about implementing it in your game, please let me know. I'll be glad to help out how I can.
     
    Hormic likes this.
  6. Hormic

    Hormic

    Joined:
    Aug 12, 2014
    Posts:
    251
    Yes, it's working now!!!
    Thank you very much, you are the hell of a developer and supporter! :)
     
  7. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Im probably going to keep it simple with one word responses. Off to watch some basic dialog system tutorials : )
     
  8. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Im having some trouble with getting started. I did the 3 Wizard setups with a player and npc, but getting a font missing exception when i run. I guess its because i already have that Font so unity wont import it again. Do i have to go through an manually assign this font to all objects in the UI Prefab im currently using?

    Also, how do i use this with a WorldSpace UI, do i have to modify a current UI prefab, or are there any world space examples i can use?
     
  9. Hormic

    Hormic

    Joined:
    Aug 12, 2014
    Posts:
    251
    I have another question regarding DS and RT-Voice.
    Is it possible that the lines from the player are also spoken and processed from RT-Voice?
     
  10. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @virror - Hmm, the default UIs generally use Unity's built-in Arial font. What UI are you using?

    By the end of Monday, I will also post a short example scene using Unity's Speech-To-Text asset (which I believe uses UnityEngine.Windows.Speech on Windows) that recognizes keywords as described in the forum post I linked to previously. I made a note to use a world space UI for the example.

    There are generic, customizable prefabs in Dialogue System > Prefabs > Unity UI Prefabs > Speech Bubble. These are speech bubble style. There's also a standard style, scifi-themed UI in the Oculus Rift VR Example Scene on the Dialogue System Extras page. It's the fifth download button in the EXTRAS section.

    Hi @Hormic - Yes. Add an RT Voice Actor component to the player. Then inspect the Dialogue Manager and tick Display Settings > Subtitle Settings > Show PC Subtitles During Line.

    If you want the player to automatically speak a line if there's only one response, instead of showing a response menu, UNtick Input Settings > Always Force Response Menu.
     
    Hormic likes this.
  11. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Thanx for the response. Managed to get all this working with some hacking, probably did it all the wrong ways : D
    But now i can start a conversation, and select responses using my voice.
    Thanx for making a great asset! :: )
     
  12. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Glad you got it working! I'll still try to get the example scene ready by Monday. If any questions come up as you work on your project, just let me know!
     
  13. wxxhrt

    wxxhrt

    Joined:
    Mar 18, 2014
    Posts:
    163
    Hi, I'm looking to use this in a project, is there support for VR gaze selection i.e. move reticule to the chosen answer and wait until a timer has sprung round? Or is something similar possible using a raycast?

    Thanks
     
  14. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    Dialogue System Menu.

    Love this by the way but i do have a question.
    How do you change the save information. So i can pick what shows up on the save and load panel, I'v read the docs and i can't seem to figure it out.
    An help would be appreciated
    Thank you

    EDIT: I have also ran into a problem with saving and RFPS.

    Im using the NPC with colliders and when they "die" they kinda drop to the ground and don't disappear.
    Iv got a gameobject as a child so when they die it disables that object and iv got the script "IncrementOnDestroy" on it for quest.
    Now when i reload the game i still want the dead bodies laying around where i left them dead from saving. Whats the easiest way to handle this? and also with them not re-spawning the drop every time i load the game please.

    Iv ran out of ideas. Thank you
     
    Last edited: Jan 9, 2017
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @wxxhrt - Today I plan to post an example using Unity's VR Samples package. This will replace the Oculus Rift Example on the Dialogue System Extras page. It will use the SelectionRadial gaze selector as described on Unity's Interaction in VR page.

    Hi
    @JACKO4590 - Let's tackle each part separately. For the save and load panel, do you mean the FPSLuaBridge component on the FPSPlayer GameObject? If so, what do you want to save/not save? If it's not working, what part isn't working (e.g., saving ammo counts)?

    I'll post a small example later today.

    You mean an item drop when they die, right? If so, I'll include that in the example.
     
  16. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    It's working as i should sorry, but what i want is to change what information it displays. currently it displays slot number, date and time. i want to change slot number to + 1 (so slot 0 will show slot 1 ect) and just add heath points, location, what mission is active and stuff like that

    it does say "If you want to record a description with saved games, set the Dialogue System variable "CurrentStage". The contents of this variable will be recorded as the saved game's description." but i am not sure on what that means.

    Yes, i coding it so they re-die at load but didn't think too ahead and the re spawn there drop

    Thanks
     
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    An update to the Menu Framework is going live on the Pixel Crushers site later today. It adds some nice features like letting you toggle fullscreen and different resolutions in the Options menu. You can also more easily customize summary info showed on saved game slots. I'll post here when it's up.

    You can define a variable "CurrentStage" in your dialogue database. When you save a game, the Menu Framework will add the current value of "CurrentStage" to the saved game's summary.

    For example, in each scene you can add a Lua Trigger set to OnStart that sets "CurrentStage" to the name of the scene.

    Or, if the player hits an important story milestone in a conversation, such as accepting a big quest, you could use a dialogue entry node's Script field to set "CurrentStage" to some text like "On the Hunt for Bigfoot" or something like that.

    Thanks. I'll check that in the upcoming example.
     
  18. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    Ahh that's how you use the "CurrentStage" So if i want to add hitpoints to that would i do something like Variable["CurrentStage"] = "Actor["Player"].hitPoints"
    Iv got to head to work but i will defiantly dig into this and see how it works together
     
    Last edited: Jan 9, 2017
  19. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Dialogue System Menu Framework - Updated

    The Menu Framework version 2017-01-09 is now on the Dialogue System Extras page. It adds:
    • Options menu: video settings - fullscreen/windowed, resolution picker, and graphics quality settings
    • Credits scene
    • More saved game UI customization
    • A bug fix related to loading scenes and persistent data components
    If you're using an older version of the Menu Framework, back up your project before importing this updated package, just to be safe.

    Hi @JACKO4590 - The updated Menu Framework also defaults to numbering slots from 1 instead of 0. The SaveHelper component has more options that you can customize, like how to record slot numbers. To add RFPS-specific info, create a C# script named IncludeRFPSHealthInSavedGames and add it to the Menu System GameObject. The script should contain this:

    IncludeRFPSHealthInSavedGames.cs
    Code (csharp):
    1. using UnityEngine;
    2. using PixelCrushers.DialogueSystem.MenuSystem;
    3.  
    4. [RequireComponent(typeof(SaveHelper))]
    5. public class IncludeRFPSHealthInSavedGames : MonoBehaviour
    6. {
    7.  
    8.     void Awake()
    9.     {
    10.         GetComponent<SaveHelper>().RecordExtraSlotDetailsHandler = AddPlayerStats;
    11.     }
    12.  
    13.     private void AddPlayerStats(int slotNum, ref string summaryInfo)
    14.     {
    15.         var fpsPlayer = FindObjectOfType<FPSPlayer>();
    16.         if (fpsPlayer != null)
    17.         {
    18.             // Add your custom info here:
    19.             summaryInfo += "\nHealth: " + fpsPlayer.hitPoints;
    20.         }      
    21.     }
    22. }
    I still owe you an example scene for this. I'm afraid I didn't have a chance to put it together today, but I'll post it as soon as I can.
     
    JACKO4590 likes this.
  20. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    Thank you soo much for this. When I get home tonight I will give it a go.

    Great work mate.
     
  21. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    It turns out the Speech-To-Text package requires a purchase of another asset, so I built the example with Wit.ai (free) and updated the Using Wit.ai Speech Recognition in Conversations article with a download link.
     
    neoshaman likes this.
  22. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @wxxhrt - The Dialogue System Extras page now has an updated VR UI example that demonstrates dialogue UIs and quest log windows in VR using the gaze selection system in Unity's free VR Samples package. It's the 5th button down in the EXTRAS section.
     
  23. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @JACKO4590 - The script below will be in the next release's RFPS Support package. Here's how you can use it on an NPC:
    1. Add a PersistentDestructible component. Assign a unique variable name to record that this NPC is dead.
    2. Edit RFPS's RemoveBody.cs script. Change the Start() method to:
      Code (csharp):
      1. public UnityEngine.Events.UnityEvent onDie;
      2. void Start (){
      3.     startTime = Time.time;
      4.     onDie.Invoke();
      5. }
    3. RFPS's RemoveBody script will now have an OnDie() event. Click the "+" to add a new entry, and assign PersistentDestructible.OnDestroy.
    4. Add the script below.
    UnregisterNPCOnDestroy.cs
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. namespace PixelCrushers.DialogueSystem.RealisticFPSPrefab
    4. {
    5.  
    6.     /// <summary>
    7.     /// If your NPC has a PersistentDestructible, it will be destroyed when you load a saved
    8.     /// game in which it's been killed. Add this script to make it gracefully unregister from
    9.     /// RFPS's NPC Registry when being destroyed.
    10.     ///
    11.     /// If you use RFPS's RemoveBody script, edit it and change the Start() method to:
    12.     ///
    13.     /// public UnityEngine.Events.UnityEvent onDie;
    14.     /// void Start()
    15.     /// {
    16.     ///     startTime = Time.time;
    17.     ///     onDie.Invoke();
    18.     /// }
    19.     ///
    20.     /// This will add an OnDie() event. Add PersistentDestructible.OnDestroy.
    21.     /// </summary>
    22.     [AddComponentMenu("Dialogue System/Third Party/Realistic FPS Prefab/Unregister NPC On Destroy (usually on NPCs)")]
    23.     [RequireComponent(typeof(AI))]
    24.     public class UnregisterNPCOnDestroy : MonoBehaviour
    25.     {
    26.  
    27.         void OnDestroy()
    28.         {
    29.             FindObjectOfType<NPCRegistry>().UnregisterNPC(GetComponent<AI>());
    30.         }
    31.     }
    32. }
     
  24. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    NullReferenceException: Object reference not set to an instance of an object
    PixelCrushers.DialogueSystem.RealisticFPSPrefab.UnregisterNPCOnDestroy.OnDestroy () (at Assets/_Scripts/UnregisterNPCOnDestroy.cs:29)

    Thats the error i get when loading a game after an enemy has died.
    I do have the script sitting on the SoldierBadNPCColliders game object (Not as a child) and have set onDie to persistent destructible.onDestroy.

    Now the script Remove body is on the game object but its not enabled. and im not sure when it enables it. Could that have something to do with it.
    Setting it on just removes the enemies on start.
     
  25. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    This means the script wasn't able to find an NPCRegistry script in the scene. If you don't have an NPCRegistry, then just remove the UnregisterNPCOnDestroy script, or change that line from:
    Code (csharp):
    1. FindObjectOfType<NPCRegistry>().UnregisterNPC(GetComponent<AI>());
    to:
    Code (csharp):
    1. var npcRegistry = FindObjectOfType<NPCRegistry>();
    2. if (npcRegistry != null) npcRegistry.UnregisterNPC(GetComponent<AI>());
    You have it correct; leave it disabled. RFPS will automatically enable it when the AI dies.
     
  26. wxxhrt

    wxxhrt

    Joined:
    Mar 18, 2014
    Posts:
    163
    Thanks Tony, this is great!
     
  27. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Happy to help! I just noticed that I must have accidentally hooked up the Quest Log button's OnClick() event to open the quest log and start the NPC's conversation. (I copied the "Talk" button to make the "Quest Log" button.) I'll fix that in the next version. But it otherwise doesn't have any bearing on actual Dialogue System-related stuff. The UIs also use the Generic template so they should be fairly easy to customize with your own textures, fonts, and layouts.
     
  28. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    ok sorry i forgot to mention the enemies are not staying dead.

    Their position is being saved and upon loading they are in their spot. But they are alive and they just walking away. Iv gone over the instructions a few times and im pretty sure i having missed anything.

    Should i have the NPCRegistry component on something in the scene?
     

    Attached Files:

  29. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @JACKO4590 - Did you add a Persistent Destructible to the enemy and assign a unique variable name such as "Soldier0001"? And set the RemoveBody's OnDie() event to call PersistentDestructible.OnDestroy?

    EDIT: Sorry, I totally missed the screenshot you attached. Try these changes:
    1. On Persistent Position Data, remove the parentheses from the variable name, and UNtick both checkboxes.
    2. On Persistent Destructible, remove the parentheses from the variable name.
    I'm not sure that the parentheses are an issue, but I'm out of the office so I can't confirm right away.


    For the NPCRegistry, take a look at the RFPS Sandbox example scene. Your NPCRegistry should be set up similarly. To find the NPCRegistry in that scene, enter "t:NPCRegistry" in the Hierarchy's search bar.
     
    Last edited: Jan 11, 2017
  30. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    ok did all that and still no go. Unticked both record level and restore level boxes and changed the variable name to soldier000x. including on the destructible script as well.
    I also found the npcRegistry, its a child component of FPS Main. so thats all set up.
    It also removes the enemy when it dies on the npcRegistry.
    It also dose not enable the removeBody script but when i manually enable it after npc dies, saving then loading makes the body disappear. instead of laying on the ground dead.

    As a side note on the whole saving thing i have notice it dose not save dropped weapons. Moved weapons are ok but once picked up and dropped it does not load them.

    Thank you for your time.
     
  31. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Ah, I forgot that you mentioned you want the dead bodies to stay around, so you're not using RemoveBody. I'll post an example later today.

    Spawned items are more challenging to save than items you've placed at design-time. (A pickup and drop counts as a newly-spawned item.) With a design-time item, the game can just record its current location and whether it still exists in the scene, and apply those changes when loading a saved game. With spawned items, the game needs to keep track of what new items have been spawned and where, and respawn them when loading a saved game.

    Fortunately this is a solved problem with the Dialogue System's UFPS integration, although it hasn't been released yet in the current version of the UFPS Support package. But it'll be fairly easy to port it to RFPS. I'll include that in the next update to the RFPS Support package.
     
  32. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Updated Makinom Support Package Available

    Makinom recently updated to version 1.6.0, which requires Unity 5.5.0+ and introduces a small API change. You can download an updated integration package on the Dialogue System Extras page!
     
  33. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @JACKO4590 - Here's the example scene: RFPS_PersistentCorpseExample_2017-01-12.unitypackage

    To use it, you'll need to download and import the updated RFPS Support package from the Dialogue System Extras page.

    Use these steps to make NPCs' positions and living/dead states persistent:
    • Add a PersistentPositionData component to save the NPC's position in saved games.

    • Add a PersistentDeadBody component (from the new RFPS Support package). Assign a unique variable name to record that this NPC is dead. (Don't use PersistentDestructible. Use RFPS Support > PersistentDeadBody instead.)

    • Edit RFPS's CharacterDamage.cs script in two places.
    On line 7 (after public class CharacterDamage : MonoBehaviour {) add:​
    Code (csharp):
    1. public UnityEngine.Events.UnityEvent onDie;
    On line ~180, change this section of the ApplyDamage method from:​
    Code (csharp):
    1. //Kill NPC
    2. if (hitPoints <= 0.0f){
    3.     AIComponent.vocalFx.Stop();
    to:
    Code (csharp):
    1. //Kill NPC
    2. if (hitPoints <= 0.0f){
    3.     onDie.Invoke(); // <---ADD THIS LINE!
    4.     AIComponent.vocalFx.Stop();
    • Remove the previously-customized lines from RemoveBody.cs. You don't need them any more since the lines have been moved to CharacterDamage.cs.

    • CharacterDamage will now have an OnDie() event. Click the "+" to add a new entry, and assign PersistentDeadBody.OnDestroy.

    • Add an UnregisterNPCOnDestroy component. (Skip if your scene doesn't have an NPCRegistry.)

    • Assign a corpse prefab to CharacterDamage's Dead Replacement field. If you don't have a corpse replacement, you can make one by copying your regular NPC prefab and removing all the RFPS-specific scripts, including the LocationDamage scripts on child GameObjects.


    In the example scene, I made these changes:
    • Gave the player an AK47 (key 5) and ticked Invulnerable.
    • Configured only the soldier in front of the house as persistent. You'll recognize him; he has a big yellow "I'M PERSISTENT!" sign over his head.
    • Created a ragdoll prefab to use as his corpse when loading saved games.

    I haven't ported over the Dialogue System's persistent pickup spawn manager to RFPS yet. I'll try to get that done this week and post here.
     
    Last edited: Jan 13, 2017
  34. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    Thank you soo much Tony. You have toi be the most supportive developer i have had the pleasure to work with.

    Regarding the unlimited save slots (like the fallout system)

    Is this still a thing thats coming out. Iv had a dig around but im not sure where to start. Would it be hard to put in and set up?
     
  35. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @JACKO4590 - Happy to help! If you run into any issues with persistent NPC dead bodies, let me know. I think all the bases should be covered on that now.

    Unlimited save slots will be in the development queue after I get the persistent pickup spawn manager ready for RFPS. In the meantime, you could add a bunch of slots using the current framework, and add a scroll view so the player can scroll up and down through them. It's not exactly unlimited slots, but it should have a similar look and feel for now.
     
  36. JACKO4590

    JACKO4590

    Joined:
    Nov 25, 2014
    Posts:
    81
    Yeah that's what Iv got going now. Just copy and paste about 10 slots. For now it will work.

    And just a side note. I changed rfps fade in to 4 seconds so when the player loads the level he dose not see the body's re drop. Works like a charm.
     
  37. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Yeah, those ragdolls starting from a standing position aren't ideal. If the player has taken down a lot of enemies nearby, without the fade it must look really creepy to load a game and see dozens of NPCs all of the sudden drop to the floor.

    An alternative to the ragdoll would be to assign a model that's already on the floor. This way you wouldn't need any fade-in at all.
     
    Last edited: Jan 13, 2017
  38. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Hi @TonyLi ,

    I was finally able to build my own interface from scratch! :p
    There's just one thing that I'd like to avoid: I'm using the same TextMeshProText UI component for showing the NPC subtitle and the subtitle reminder when a response is needed.

    But, currently (I'm using a modified version of the "fading" UI class you kindly provided) when an NPC dialogue node is followed by a response, the panel gets deactivated for a moment and reappears about half a second after (seems to be a bit random, maybe it's dialogue text length dependent?).

    Is there a way to avoid it to hide? It gets deactivated when a response is made, along with the other options fading.
    I think it would be nice to have it blink a bit when switching NPC nodes, but when a response is needed I'd like to avoid it.

    Which method should I be overriding, or doing some checks into?

    Also, I have a "gesticulate" bool field in the conversations template, where is the best place to check its value to play the animation when a NPC node is started and its gesticulate is true, and in the same instant the player makes a choice?

    This is the default Response UI:


    and the NPC Subtitle UI is basically the same, but without the two responses boxes.
    (I'm also having a hard time with the button resizing logic but that's more a UI issue than a DS one - basically if the text is less than a line the sizing should be minimal, but instead of expanding it to the full width horizontally I'd like to try to keep a rectangular shape until the maximum width has been reached, and expanding vertically when max width has been reached)

    Here's the code I'm using (basically your code with a few changes since I'm not using button templates but fixed ones (I always have 2 answers). Warning: leftovers/commented code still present :p

    Fade duration is set to 1
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using PixelCrushers.DialogueSystem.TextMeshPro;
    4. using PixelCrushers.DialogueSystem;
    5.  
    6. /// <summary>
    7. /// This subclass of TextMeshProDialogueUI keeps the response menu visible
    8. /// after the player clicks a response, but fades out all but the clicked
    9. /// button and makes them all non-interactive. The response button should
    10. /// have a CanvasGroup component. I used a CanvasGroup instead of an
    11. /// Animator because a bug in Unity UI prevents Buttons from playing nicely
    12. /// with Animators on the same GameObject.
    13. /// </summary>
    14. public class FNSDialogueUI : TextMeshProDialogueUI
    15. {
    16.  
    17.     public float responseFadeDuration = 1f;
    18.  
    19.     protected GameObject clickedButtonGO = null;
    20.  
    21.     public void RecordClickedButton(GameObject buttonGO)
    22.     {
    23.         clickedButtonGO = buttonGO;
    24.     }
    25.  
    26.     public override void ShowSubtitle(Subtitle subtitle)
    27.     {
    28.         base.ShowSubtitle(subtitle);
    29.         if (subtitle.speakerInfo.IsNPC)
    30.         {
    31.             //restore button alpha
    32.             //dialogue.responseMenu.Hide();
    33.             //dialogue.responseMenu.DestroyInstantiatedButtons();
    34.         }
    35.     }
    36.  
    37.     public override void HideResponses()
    38.     {
    39.         // Don't actually hide the responses right away.
    40.         // Instead, hide the subtitle reminder:
    41.         dialogue.responseMenu.subtitleReminder.Hide();
    42.      
    43.         // And then fade out all responses except the clicked one,
    44.         // and make them all non-interactive:
    45.         foreach (var tmp in dialogue.responseMenu.buttons)
    46.         {
    47.             GameObject buttonGO = tmp.gameObject;
    48.             var button = buttonGO.GetComponent<UnityEngine.UI.Button>();
    49.             if (button != null)
    50.             {
    51.                 button.interactable = false;
    52.             }
    53.             if (buttonGO != clickedButtonGO && buttonGO.activeInHierarchy)
    54.             {
    55.                 StartCoroutine(FadeCanvasGroup(buttonGO.GetComponent<CanvasGroup>()));
    56.             }
    57.         }
    58.      
    59.         StartCoroutine("HideAndRestoreResponses");
    60.     }
    61.  
    62.     public override void ShowResponses(Subtitle subtitle, Response[] responses, float timeout)
    63.     {
    64.         base.ShowResponses(subtitle, responses, timeout);
    65.      
    66.         dialogue.responseMenu.buttons[0].GetComponent<CanvasGroup>().alpha = 1;
    67.         dialogue.responseMenu.buttons[1].GetComponent<CanvasGroup>().alpha = 1;
    68.     }
    69.  
    70.     protected virtual IEnumerator HideAndRestoreResponses()
    71.     {
    72.         yield return new WaitForSeconds(2);
    73.      
    74.         dialogue.ResponseMenu.Hide();
    75.         clickedButtonGO = null;
    76.     }
    77.  
    78.     protected IEnumerator FadeCanvasGroup(CanvasGroup canvasGroup)
    79.     {
    80.         if (responseFadeDuration > 0)
    81.         {
    82.             float elapsed = 0;
    83.             while (elapsed < responseFadeDuration)
    84.             {
    85.                 if (canvasGroup == null) yield break; // May not exist or may get destroyed by next NPC line.
    86.                 canvasGroup.gameObject.SetActive(true);
    87.                 canvasGroup.alpha = Mathf.Min(canvasGroup.alpha, 1 - elapsed / responseFadeDuration);
    88.                 yield return null;
    89.                 elapsed += Time.deltaTime;
    90.             }
    91.         }
    92.         if (canvasGroup == null) canvasGroup.alpha = 0;
    93.     }
    94. }
    95.  
    Set this way:



    with this dialogue hierarchy (again there are leftovers here, for reference), I'm not 100% sure this is the best way to implement this:


    I also have this code (adapted a little from the version you wrote) on the Onclick events of the responses buttons:
    Code (CSharp):
    1. using UnityEngine;
    2. using PixelCrushers.DialogueSystem.TextMeshPro;
    3.  
    4. /// <summary>
    5. /// This script works in conjunction with TMProFadeDialogueUI. Add it to
    6. /// your response button template, and replace the button's OnClick() event
    7. /// with this script's OnClick method.
    8. /// </summary>
    9. [RequireComponent(typeof(TextMeshProResponseButton))]
    10. public class RecordClickedButtonInFNSDialogueUI : MonoBehaviour
    11. {
    12.  
    13.     [Tooltip("Assign the FNS Dialogue UI. If unassigned, this script will try to find it at runtime.")]
    14.     public FNSDialogueUI dialogueUI;
    15.  
    16.     public void OnClick()
    17.     {
    18.         Debug.LogFormat("{0} has been clicked!", name);
    19.         if (dialogueUI == null) dialogueUI = FindObjectOfType<FNSDialogueUI>();
    20.         if (dialogueUI != null) dialogueUI.RecordClickedButton(this.gameObject);
    21.         GetComponent<TextMeshProResponseButton>().OnClick();
    22.     }
    23.  
    24. }
    25.  
    I think the Dialogue UI settings could be important as well:


    this is all the info I could give on a post :)
    Do you have any clue about what's going on? Could you please have a look?

    Thanks for your time.
     
    Last edited: Jan 14, 2017
  39. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @NeatWolf - What if you tick Always Visible in the NPC Subtitle section and the Response Menu > Subtitle Reminder section?

    If that's not what you're looking for, here's the logic behind the dialogue UI method:
    • ShowSubtitle(): Activates the subtitle UI elements (e.g., NPC Subtitle section).
    • HideSubtitle(): Deactivates the subtitle UI elements, unless Always Visible is ticked.
    • ShowResponses(): Activates the response menu UI elements, including Subtitle Reminder.
    • HideResponses(): Deactivates the response menu UI elements, including Subtitle Reminder (unless Always Visible).
    There are some nuances. If you've assigned Animation Transitions (Show & Hide), the dialogue UI will wait until the Hide animation is done before deactivating the UI elements.

    When the Dialogue UI shows an NPC line, it calls ShowSubtitle(). When the line is done, it calls HideSubtitle(). If the next stage of the conversation is a response menu, it calls ShowResponses(). When the player chooses a response, it calls HideResponses().

    Please also feel free to send an example to tony (at) pixelcrushers.com. I'll be happy to take a look.

    Can you please clarify a few things for me? This is my understanding: If the conversation's "gesticulate" bool is true, then when a character speaks a line (either an NPC subtitle or player response), play an animation on that character. Is that correct?

    If that's correct, here are two different suggestions to implement it:

    1. Since you already have the "gesticulate" bool set up, add a script to the Dialogue Manager with an OnConversationLine method. Something like:
    Code (csharp):
    1. void OnConversationLine(Subtitle subtitle) {
    2.     var conversationID = DialogueManager.CurrentConversationState.subtitle.dialogueEntry.conversationID;
    3.     var conversation = DialogueManager.MasterDatabase.GetConversation(conversationID);
    4.     var gesticulate = conversation.LookupBool("gesticulate");
    5.     if (gesticulate) {
    6.         var character = DialogueManager.CurrentConversationState.speakerInfo.transform;
    7.         character.GetComponent<Animator>().Play("gesticulate");
    8.     }
    9. }
    2. Or, don't use the "gesticulate" bool, and instead build it into the conversation's properties. To do this, inspect the conversation properties and tick Override Display Settings. Then tick Sequence Settings, and set Default Sequence to use something like AnimatorPlay():
    Code (sequencer):
    1. AnimatorPlay(gesticulate); AnimatorPlay(idle)@{{end}}
     
  40. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Thanks for your timely answer, @TonyLi!

    I'm about to send you more details via email

    I didn't expain it well.

    for each node of the dialogue I can have one of the actor to play or not some talking animation according to the bool value of a field.
    At the moment I only have a bool for each node, but in the future we could also use specific animations for each node.
     
  41. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Will suggestion #2 above work then? Let's say your character has a specific animator state for each node. If you name the animator states using entrytags, you can set the Dialogue Manager's Default Sequence to something like:
    Code (sequencer):
    1. AnimatorPlayWait(entrytag)
    If you've also recorded voiceover lines for each node, name them also according to their entrytags, and play them like this:
    Code (sequencer):
    1. AnimatorPlayWait(entrytag);
    2. AudioWait(entrytag)
    If I misunderstood your goal, would it be possible for you to describe a concrete example? It can be hypothetical; it doesn't have to be from your actual project.
     
  42. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    Tony,
    Using chatmapper I can do multiple If tests in the script box.

    When it runs, I get exceptions. I have spent a few hours looking for the answer but I cannot seem to find it.

    if Item["QuickStart"].Entry_1_State == "unassigned" then
    Item["QuickStart"].Entry_1_State = "active"
    end ;
    if Variable["CommonState"] == 10 then
    Variable["CommonState"] = 19
    end

    Thanks

    David
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Hi @Mazak - Does it run correctly in Chat Mapper's Simulator? Maybe there's a typo.

    When you import into Unity, does it report any errors or warnings?

    I pasted your script text into a test scene and it works. Here's the scene if you want to compare it with yours:

    TestLua_2017-01-15.unitypackage

    It has 2 buttons: one to use a Chat Mapper-generated dialogue database, and another to use an equivalent database written using the built-in editor. The scene folder also includes the Chat Mapper project I used. I exported this from Unity 5.3.4 and Dialogue System 1.6.7.

    If that doesn't help, please feel free to send a reproduction project to tony (at) pixelcrushers.com and let me know what version of Unity to use. I'll be happy to take a look.
     
  44. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    Thanks Tony,
    I thought it should work, if I still have trouble later I will let you know.

    the ';' should separate the two if's right?

    It gets to the second if test and gives me a bazillion parser errors. (or it was last night)

    Yes, it is perfect in chat mapper.
     
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    That's right. I pasted your code verbatim into the example scene/Chat Mapper file, and it worked.
     
  46. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    Well this is what I'm getting now:
    Dialogue System: Lua code 'Tut_QuickStart("Display_Building, all, on");
    if Item["QuickStart"].Entry_1_State ~= "unassigned" then
    if Variable["SY_Workers"] < 360 then
    Item["QuickStart"].Entry_1_State = "active"
    else
    Item["QuickStart"].Entry_1_State = "success"
    end
    end;
    UpdateTracker();' threw exception 'Code has syntax errors:
    Line 3, Col 7 'a': Failed to parse Letter of Name.
    Line 3, Col 7 'a': Failed to parse Name of VarName.
    Line 3, Col 7 'a': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 7 'a': Failed to parse Text of BoolLiteral.
    Line 3, Col 7 'a': Failed to parse '0'...'9' of Digit.
    Line 3, Col 7 'a': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 7 'a': Failed to parse Name of VariableArg.
    Line 3, Col 7 'a': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 7 'a': Failed to parse Expr of ExprStmt.
    Line 3, Col 7 'a': Failed to parse Letter of Name.
    Line 3, Col 7 'a': Failed to parse Name of VarName.
    Line 3, Col 7 'a': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 7 'a': Failed to parse Text of BoolLiteral.
    Line 3, Col 7 'a': Failed to parse '0'...'9' of Digit.
    Line 3, Col 7 'a': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 7 'a': Failed to parse Name of VariableArg.
    Line 3, Col 7 'a': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 7 'a': Failed to parse Expr of ExprStmt.
    Line 3, Col 2 ' ': Failed to parse Letter of Name.
    Line 3, Col 2 ' ': Failed to parse Name of VarName.
    Line 3, Col 2 ' ': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 2 ' ': Failed to parse Text of BoolLiteral.
    Line 3, Col 2 ' ': Failed to parse '0'...'9' of Digit.
    Line 3, Col 2 ' ': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 2 ' ': Failed to parse Name of VariableArg.
    Line 3, Col 2 ' ': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 2 ' ': Failed to parse Expr of ExprStmt.
    Line 3, Col 7 'a': Failed to parse Letter of Name.
    Line 3, Col 7 'a': Failed to parse Name of VarName.
    Line 3, Col 7 'a': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 7 'a': Failed to parse Text of BoolLiteral.
    Line 3, Col 7 'a': Failed to parse '0'...'9' of Digit.
    Line 3, Col 7 'a': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 7 'a': Failed to parse Name of VariableArg.
    Line 3, Col 7 'a': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 7 'a': Failed to parse Expr of ExprStmt.
    Line 10, Col 1 : Failed to parse Letter of Name.
    Line 10, Col 1 : Failed to parse Name of VarName.
    Line 10, Col 1 : Failed to parse 'nil' of NilLiteral.
    Line 10, Col 1 : Failed to parse Text of BoolLiteral.
    Line 10, Col 1 : Failed to parse '0'...'9' of Digit.
    Line 10, Col 1 : Failed to parse (Digit)+ of FloatNumber.
    Line 10, Col 1 : Failed to parse Name of VariableArg.
    Line 10, Col 1 : Failed to parse firstTerm of OperatorExpr.
    Line 10, Col 1 : Failed to parse Expr of ExprStmt.
    Line 1, Col 23 'y': Failed to parse Letter of Name.
    Line 1, Col 23 'y': Failed to parse Name of VarName.
    Line 1, Col 23 'y': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 23 'y': Failed to parse Text of BoolLiteral.
    Line 1, Col 23 'y': Failed to parse '0'...'9' of Digit.
    Line 1, Col 23 'y': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 23 'y': Failed to parse Name of VariableArg.
    Line 1, Col 23 'y': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 23 'y': Failed to parse Expr of ExprStmt.
    Line 1, Col 31 'n': Failed to parse Letter of Name.
    Line 1, Col 31 'n': Failed to parse Name of VarName.
    Line 1, Col 31 'n': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 31 'n': Failed to parse Text of BoolLiteral.
    Line 1, Col 31 'n': Failed to parse '0'...'9' of Digit.
    Line 1, Col 31 'n': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 31 'n': Failed to parse Name of VariableArg.
    Line 1, Col 31 'n': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 31 'n': Failed to parse Expr of ExprStmt.
    Line 1, Col 25 'B': Failed to parse Letter of Name.
    Line 1, Col 25 'B': Failed to parse Name of VarName.
    Line 1, Col 25 'B': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 25 'B': Failed to parse Text of BoolLiteral.
    Line 1, Col 25 'B': Failed to parse '0'...'9' of Digit.
    Line 1, Col 25 'B': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 25 'B': Failed to parse Name of VariableArg.
    Line 1, Col 25 'B': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 25 'B': Failed to parse Expr of ExprStmt.
    Line 1, Col 28 'l': Failed to parse Letter of Name.
    Line 1, Col 28 'l': Failed to parse Name of VarName.
    Line 1, Col 28 'l': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 28 'l': Failed to parse Text of BoolLiteral.
    Line 1, Col 28 'l': Failed to parse '0'...'9' of Digit.
    Line 1, Col 28 'l': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 28 'l': Failed to parse Name of VariableArg.
    Line 1, Col 28 'l': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 28 'l': Failed to parse Expr of ExprStmt.
    Line 1, Col 31 'n': Failed to parse Letter of Name.
    Line 1, Col 31 'n': Failed to parse Name of VarName.
    Line 1, Col 31 'n': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 31 'n': Failed to parse Text of BoolLiteral.
    Line 1, Col 31 'n': Failed to parse '0'...'9' of Digit.
    Line 1, Col 31 'n': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 31 'n': Failed to parse Name of VariableArg.
    Line 1, Col 31 'n': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 31 'n': Failed to parse Expr of ExprStmt.
    Line 1, Col 30 'i': Failed to parse Letter of Name.
    Line 1, Col 30 'i': Failed to parse Name of VarName.
    Line 1, Col 30 'i': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 30 'i': Failed to parse Text of BoolLiteral.
    Line 1, Col 30 'i': Failed to parse '0'...'9' of Digit.
    Line 1, Col 30 'i': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 30 'i': Failed to parse Name of VariableArg.
    Line 1, Col 30 'i': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 30 'i': Failed to parse Expr of ExprStmt.
    Line 1, Col 29 'd': Failed to parse Letter of Name.
    Line 1, Col 29 'd': Failed to parse Name of VarName.
    Line 1, Col 29 'd': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 29 'd': Failed to parse Text of BoolLiteral.
    Line 1, Col 29 'd': Failed to parse '0'...'9' of Digit.
    Line 1, Col 29 'd': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 29 'd': Failed to parse Name of VariableArg.
    Line 1, Col 29 'd': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 29 'd': Failed to parse Expr of ExprStmt.
    Line 1, Col 30 'i': Failed to parse Letter of Name.
    Line 1, Col 30 'i': Failed to parse Name of VarName.
    Line 1, Col 30 'i': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 30 'i': Failed to parse Text of BoolLiteral.
    Line 1, Col 30 'i': Failed to parse '0'...'9' of Digit.
    Line 1, Col 30 'i': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 30 'i': Failed to parse Name of VariableArg.
    Line 1, Col 30 'i': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 30 'i': Failed to parse Expr of ExprStmt.
    Line 1, Col 34 ' ': Failed to parse Letter of Name.
    Line 1, Col 34 ' ': Failed to parse Name of VarName.
    Line 1, Col 34 ' ': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 34 ' ': Failed to parse Text of BoolLiteral.
    Line 1, Col 34 ' ': Failed to parse '0'...'9' of Digit.
    Line 1, Col 34 ' ': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 34 ' ': Failed to parse Name of VariableArg.
    Line 1, Col 34 ' ': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 34 ' ': Failed to parse Expr of ExprStmt.
    Line 1, Col 28 'l': Failed to parse Letter of Name.
    Line 1, Col 28 'l': Failed to parse Name of VarName.
    Line 1, Col 28 'l': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 28 'l': Failed to parse Text of BoolLiteral.
    Line 1, Col 28 'l': Failed to parse '0'...'9' of Digit.
    Line 1, Col 28 'l': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 28 'l': Failed to parse Name of VariableArg.
    Line 1, Col 28 'l': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 28 'l': Failed to parse Expr of ExprStmt.
    Line 1, Col 28 'l': Failed to parse Letter of Name.
    Line 1, Col 28 'l': Failed to parse Name of VarName.
    Line 1, Col 28 'l': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 28 'l': Failed to parse Text of BoolLiteral.
    Line 1, Col 28 'l': Failed to parse '0'...'9' of Digit.
    Line 1, Col 28 'l': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 28 'l': Failed to parse Name of VariableArg.
    Line 1, Col 28 'l': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 28 'l': Failed to parse Expr of ExprStmt.
    Line 3, Col 28 ' ': Failed to parse Letter of Name.
    Line 3, Col 28 ' ': Failed to parse Name of VarName.
    Line 3, Col 28 ' ': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 28 ' ': Failed to parse Text of BoolLiteral.
    Line 3, Col 28 ' ': Failed to parse '0'...'9' of Digit.
    Line 3, Col 28 ' ': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 28 ' ': Failed to parse Name of VariableArg.
    Line 3, Col 28 ' ': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 28 ' ': Failed to parse Expr of ExprStmt.
    Line 3, Col 24 'r': Failed to parse Letter of Name.
    Line 3, Col 24 'r': Failed to parse Name of VarName.
    Line 3, Col 24 'r': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 24 'r': Failed to parse Text of BoolLiteral.
    Line 3, Col 24 'r': Failed to parse '0'...'9' of Digit.
    Line 3, Col 24 'r': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 24 'r': Failed to parse Name of VariableArg.
    Line 3, Col 24 'r': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 24 'r': Failed to parse Expr of ExprStmt.
    Line 3, Col 33 '0': Failed to parse Letter of Name.
    Line 3, Col 33 '0': Failed to parse Name of VarName.
    Line 3, Col 33 '0': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 33 '0': Failed to parse Text of BoolLiteral.
    Line 3, Col 33 '0': Failed to parse '0'...'9' of Digit.
    Line 3, Col 33 '0': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 33 '0': Failed to parse Name of VariableArg.
    Line 3, Col 33 '0': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 33 '0': Failed to parse Expr of ExprStmt.
    Line 3, Col 26 '"': Failed to parse Letter of Name.
    Line 3, Col 26 '"': Failed to parse Name of VarName.
    Line 3, Col 26 '"': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 26 '"': Failed to parse Text of BoolLiteral.
    Line 3, Col 26 '"': Failed to parse '0'...'9' of Digit.
    Line 3, Col 26 '"': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 26 '"': Failed to parse Name of VariableArg.
    Line 3, Col 26 '"': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 26 '"': Failed to parse Expr of ExprStmt.
    Line 3, Col 32 '6': Failed to parse Letter of Name.
    Line 3, Col 32 '6': Failed to parse Name of VarName.
    Line 3, Col 32 '6': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 32 '6': Failed to parse Text of BoolLiteral.
    Line 3, Col 32 '6': Failed to parse '0'...'9' of Digit.
    Line 3, Col 32 '6': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 32 '6': Failed to parse Name of VariableArg.
    Line 3, Col 32 '6': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 32 '6': Failed to parse Expr of ExprStmt.
    Line 3, Col 38 'n': Failed to parse Letter of Name.
    Line 3, Col 38 'n': Failed to parse Name of VarName.
    Line 3, Col 38 'n': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 38 'n': Failed to parse Text of BoolLiteral.
    Line 3, Col 38 'n': Failed to parse '0'...'9' of Digit.
    Line 3, Col 38 'n': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 38 'n': Failed to parse Name of VariableArg.
    Line 3, Col 38 'n': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 38 'n': Failed to parse Expr of ExprStmt.
    Line 3, Col 34 ' ': Failed to parse Letter of Name.
    Line 3, Col 34 ' ': Failed to parse Name of VarName.
    Line 3, Col 34 ' ': Failed to parse 'nil' of NilLiteral.
    Line 3, Col 34 ' ': Failed to parse Text of BoolLiteral.
    Line 3, Col 34 ' ': Failed to parse '0'...'9' of Digit.
    Line 3, Col 34 ' ': Failed to parse (Digit)+ of FloatNumber.
    Line 3, Col 34 ' ': Failed to parse Name of VariableArg.
    Line 3, Col 34 ' ': Failed to parse firstTerm of OperatorExpr.
    Line 3, Col 34 ' ': Failed to parse Expr of ExprStmt.
    Line 1, Col 12 'a': Failed to parse Letter of Name.
    Line 1, Col 12 'a': Failed to parse Name of VarName.
    Line 1, Col 12 'a': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 12 'a': Failed to parse Text of BoolLiteral.
    Line 1, Col 12 'a': Failed to parse '0'...'9' of Digit.
    Line 1, Col 12 'a': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 12 'a': Failed to parse Name of VariableArg.
    Line 1, Col 12 'a': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 12 'a': Failed to parse Expr of ExprStmt.
    Line 2, Col 21 ']': Failed to parse Letter of Name.
    Line 2, Col 21 ']': Failed to parse Name of VarName.
    Line 2, Col 21 ']': Failed to parse 'nil' of NilLiteral.
    Line 2, Col 21 ']': Failed to parse Text of BoolLiteral.
    Line 2, Col 21 ']': Failed to parse '0'...'9' of Digit.
    Line 2, Col 21 ']': Failed to parse (Digit)+ of FloatNumber.
    Line 2, Col 21 ']': Failed to parse Name of VariableArg.
    Line 2, Col 21 ']': Failed to parse firstTerm of OperatorExpr.
    Line 2, Col 21 ']': Failed to parse Expr of ExprStmt.
    Line 1, Col 32 'g': Failed to parse Letter of Name.
    Line 1, Col 32 'g': Failed to parse Name of VarName.
    Line 1, Col 32 'g': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 32 'g': Failed to parse Text of BoolLiteral.
    Line 1, Col 32 'g': Failed to parse '0'...'9' of Digit.
    Line 1, Col 32 'g': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 32 'g': Failed to parse Name of VariableArg.
    Line 1, Col 32 'g': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 32 'g': Failed to parse Expr of ExprStmt.
    Line 1, Col 44 ';': Failed to parse Letter of Name.
    Line 1, Col 44 ';': Failed to parse Name of VarName.
    Line 1, Col 44 ';': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 44 ';': Failed to parse Text of BoolLiteral.
    Line 1, Col 44 ';': Failed to parse '0'...'9' of Digit.
    Line 1, Col 44 ';': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 44 ';': Failed to parse Name of VariableArg.
    Line 1, Col 44 ';': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 44 ';': Failed to parse Expr of ExprStmt.
    Line 1, Col 12 'a': Failed to parse Letter of Name.
    Line 1, Col 12 'a': Failed to parse Name of VarName.
    Line 1, Col 12 'a': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 12 'a': Failed to parse Text of BoolLiteral.
    Line 1, Col 12 'a': Failed to parse '0'...'9' of Digit.
    Line 1, Col 12 'a': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 12 'a': Failed to parse Name of VariableArg.
    Line 1, Col 12 'a': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 12 'a': Failed to parse Expr of ExprStmt.
    Line 2, Col 21 ']': Failed to parse Letter of Name.
    Line 2, Col 21 ']': Failed to parse Name of VarName.
    Line 2, Col 21 ']': Failed to parse 'nil' of NilLiteral.
    Line 2, Col 21 ']': Failed to parse Text of BoolLiteral.
    Line 2, Col 21 ']': Failed to parse '0'...'9' of Digit.
    Line 2, Col 21 ']': Failed to parse (Digit)+ of FloatNumber.
    Line 2, Col 21 ']': Failed to parse Name of VariableArg.
    Line 2, Col 21 ']': Failed to parse firstTerm of OperatorExpr.
    Line 2, Col 21 ']': Failed to parse Expr of ExprStmt.
    Line 1, Col 32 'g': Failed to parse Letter of Name.
    Line 1, Col 32 'g': Failed to parse Name of VarName.
    Line 1, Col 32 'g': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 32 'g': Failed to parse Text of BoolLiteral.
    Line 1, Col 32 'g': Failed to parse '0'...'9' of Digit.
    Line 1, Col 32 'g': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 32 'g': Failed to parse Name of VariableArg.
    Line 1, Col 32 'g': Failed to parse firstTerm of OperatorExpr.
    Line 1, Col 32 'g': Failed to parse Expr of ExprStmt.
    Line 1, Col 45 '
    ': Failed to parse Letter of Name.
    Line 1, Col 45 '
    ': Failed to parse Name of VarName.
    Line 1, Col 45 '
    ': Failed to parse 'nil' of NilLiteral.
    Line 1, Col 45 '
    ': Failed to parse Text of BoolLiteral.
    Line 1, Col 45 '
    ': Failed to parse '0'...'9' of Digit.
    Line 1, Col 45 '
    ': Failed to parse (Digit)+ of FloatNumber.
    Line 1, Col 45 '
    ': Failed to parse Name of VariableArg.
    Line 1, Col 45 '
    ': Failed to parse firstTerm of O<message truncated>
     
  47. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @Mazak - It looks like a quirk with LuaInterpreter's parser. I'll fix it in the next release. In the meantime, a quick fix is to remove the semicolon after the "end" keyword. In Lua, semicolons aren't required if you have a line break. In other words:
    Code (Lua):
    1. Tut_QuickStart("Display_Building, all, on");
    2. if Item["QuickStart"].Entry_1_State ~= "unassigned" then
    3.   if Variable["SY_Workers"] < 360 then
    4.     Item["QuickStart"].Entry_1_State = "active"
    5.   else
    6.     Item["QuickStart"].Entry_1_State = "success"
    7.   end
    8. end
    9. UpdateTracker();
    On line 8 above, I removed the semicolon.

    (Sorry, I know how frustrating that must have been.)
     
    Mazak likes this.
  48. Mazak

    Mazak

    Joined:
    Mar 24, 2013
    Posts:
    226
    ha ha ha!

    I discovered the same thing!

    This works fine:
    if Variable["CommonState"] == 0 then Variable["CommonState"] = 1 end

    This throws and exception
    if Variable["CommonState"] == 0 then Variable["CommonState"] = 1 end;

    Fantastic! Thanks Tony!
     
  49. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Glad I could help! Sorry it turned out to be a quirk in the parser. Every implementation of a language has its quirks (for example, MonoDevelop compiles some C# code differently than VS), but they're always frustrating to encounter. I chose LuaInterpreter because it's a lean, native C# implementation, but I guess that one got past me (at least until version 1.6.8!).

    If you're not already using it, you might find the Lua Console component to be helpful, or the Lua example scene. If you want to test out some Lua code really quick, you can paste it into the console. It's also useful to change values at runtime. I'll sometimes do this to advance quest states or give myself extra ammo while debugging.
     
    Mazak likes this.
  50. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Updated ORK Framework Support Package Available

    The Dialogue System Extras page has an updated integration package for ORK Framework. It adds event steps to control quests and quest entries, and the example scene adds a very simple quest to talk to an NPC. Since the latest version of ORK now requires Unity 5.5.0+, this package was exported in Unity 5.5.0.