Multiple Small Questions regarding the Dialogue System
Multiple Small Questions regarding the Dialogue System
Hi, this is my first time posting here. I just want to begin by saying that this is an amazing asset you've created, and it's been quite fun for the most part to learn. I had a few questions on how to finish up customizing my UIs and conversations.
-Variables: I've set up an example conversation where talking to the NPC increases a variable each time, allowing for different texts. I thought this would be useful for interactable objects, as they could each have an instance of this variable that raises when examined. I had this setup in a previous engine I've now abandoned, and it worked amazingly, but I've yet to determine how to do this in Unity. While I do know a bit of C#, I'm unfamiliar with both Lua and the methods and classes of this asset. This seems easy in my head, but I need a nudge in the correct direction.
-Hiding Portraits and Names: On that note, I need to be able to easily hide the portrait section of the UI. I've pretty heavily customized the JRPG template and have everything related to portraits under the Portrait Panel, but I don't know how to disable and reenable this as needed through Lua or C#. I should note that I have almost no experience working with UI using direct code, and learning from this asset has actually been my first real experience working with UI entirely! I found many results related to this topic in my searches, but nothing exactly matching my needs.
-Cancelled Conversations: I've found some settings related to cancelling the conversation when the player walks away. This works great on its own, but I'd also like to change a variable noting that the player walked away from the conversation, and have the NPC react to it, maybe with a bark at that moment or a different conversation when you next talk to them. I'm unsure how to trigger the variable change when this happens, unfortunately.
-Keyboard Navigation: I'm sorry, I'm sure you get asked this a lot, but I just wasn't able to figure it out, even after looking it up. I want to navigate dialogue choices using the keyboard. I tried to enable this by adding the GUI Control script to the Response Menu Panel and enabling the Navigation option, but this didn't work. I think I'm close, however. The other issue is that the same keys used for movement would also be used for navigation, so I'd need the player to be able to move around (and potentially cancel the conversation if they wander off) until a choice comes up, which would prevent the player from moving while the choice remains on-screen.
Items: The items variable sticks out to me because of how little functionality it has. Just a name, description, and seemingly the ability to instance it?? I don't know. Am I missing something here? What is this for?
I'm really sorry if a lot of these questions are just me being dumb, but thank you in advance for any help you can give me.
Edit: Just remembered. I'd also like to ask about text appearing one character at a time. I saw a setting for "Typewriter text"? Or something like that anyway. I wanted dialogue text to appear .. not all at once, if you understand. Is this possible, and if so, how? Also being able to adjust the speed of the text would be nice.
-Variables: I've set up an example conversation where talking to the NPC increases a variable each time, allowing for different texts. I thought this would be useful for interactable objects, as they could each have an instance of this variable that raises when examined. I had this setup in a previous engine I've now abandoned, and it worked amazingly, but I've yet to determine how to do this in Unity. While I do know a bit of C#, I'm unfamiliar with both Lua and the methods and classes of this asset. This seems easy in my head, but I need a nudge in the correct direction.
-Hiding Portraits and Names: On that note, I need to be able to easily hide the portrait section of the UI. I've pretty heavily customized the JRPG template and have everything related to portraits under the Portrait Panel, but I don't know how to disable and reenable this as needed through Lua or C#. I should note that I have almost no experience working with UI using direct code, and learning from this asset has actually been my first real experience working with UI entirely! I found many results related to this topic in my searches, but nothing exactly matching my needs.
-Cancelled Conversations: I've found some settings related to cancelling the conversation when the player walks away. This works great on its own, but I'd also like to change a variable noting that the player walked away from the conversation, and have the NPC react to it, maybe with a bark at that moment or a different conversation when you next talk to them. I'm unsure how to trigger the variable change when this happens, unfortunately.
-Keyboard Navigation: I'm sorry, I'm sure you get asked this a lot, but I just wasn't able to figure it out, even after looking it up. I want to navigate dialogue choices using the keyboard. I tried to enable this by adding the GUI Control script to the Response Menu Panel and enabling the Navigation option, but this didn't work. I think I'm close, however. The other issue is that the same keys used for movement would also be used for navigation, so I'd need the player to be able to move around (and potentially cancel the conversation if they wander off) until a choice comes up, which would prevent the player from moving while the choice remains on-screen.
Items: The items variable sticks out to me because of how little functionality it has. Just a name, description, and seemingly the ability to instance it?? I don't know. Am I missing something here? What is this for?
I'm really sorry if a lot of these questions are just me being dumb, but thank you in advance for any help you can give me.
Edit: Just remembered. I'd also like to ask about text appearing one character at a time. I saw a setting for "Typewriter text"? Or something like that anyway. I wanted dialogue text to appear .. not all at once, if you understand. Is this possible, and if so, how? Also being able to adjust the speed of the text would be nice.
Re: Multiple Small Questions regarding the Dialogue System
Hi,
Thanks for using the Dialogue System!
One thing to note: Conversations Evaluate Conditions One Extra Level Ahead
Also related: How To: Run a Conversation Only Once / Different Second Time
1. Without scripting, although somewhat awkward: Set the "walked away" variable to true at the start of the conversation. In the last dialogue entry node of the conversation, set the variable false.
2. With scripting: Make a subclass of DialogueSystemTrigger and use this in place of DialogueSystemTrigger. Override the StopActiveConversation() method. Example:
To adjust the speed, set the typewriter effect's Characters Per Second. You can also add RPG Maker-style control codes into your text to make it pause, appear immediately, etc.
If you're using continue buttons to advance the conversation, you may want the first click of a continue button to fast-forward the typewriter if it's still typing. The UI prefabs that ship with the Dialogue System behave like this. They use StandardUIContinueButtonFastForward components.
If you want to change the typewriter speed at runtime, see: How To: Adjust Typewriter Speed.
Thanks for using the Dialogue System!
No need for any scripting. Define your variable in the Dialogue Editor's Variable section. In the first dialogue entry node of your conversation (the node linked from <START>), click the "..." next to the Script field. Click "+", then set the dropdowns to Set > Variable > (your-variable-name) > Add > 1. Then click Apply. This will increment your variable every time the conversation starts.The_Kihng wrote: ↑Fri Aug 25, 2023 4:17 pm-Variables: I've set up an example conversation where talking to the NPC increases a variable each time, allowing for different texts. I thought this would be useful for interactable objects, as they could each have an instance of this variable that raises when examined. I had this setup in a previous engine I've now abandoned, and it worked amazingly, but I've yet to determine how to do this in Unity. While I do know a bit of C#, I'm unfamiliar with both Lua and the methods and classes of this asset. This seems easy in my head, but I need a nudge in the correct direction.
One thing to note: Conversations Evaluate Conditions One Extra Level Ahead
Also related: How To: Run a Conversation Only Once / Different Second Time
Try this:The_Kihng wrote: ↑Fri Aug 25, 2023 4:17 pm-Hiding Portraits and Names: On that note, I need to be able to easily hide the portrait section of the UI. I've pretty heavily customized the JRPG template and have everything related to portraits under the Portrait Panel, but I don't know how to disable and reenable this as needed through Lua or C#. I should note that I have almost no experience working with UI using direct code, and learning from this asset has actually been my first real experience working with UI entirely! I found many results related to this topic in my searches, but nothing exactly matching my needs.
- Make sure the GameObject named "Portrait Panel" is uniquely named. If not, give it a unique name.
- Add a Canvas Group component to the portrait panel. Set its Alpha to zero. Then disable the Canvas Group by unticking the checkbox next to the component name.
- When you want to hide the portrait panel, use this sequencer command in your dialogue entry node:The {{default}} runs the Dialogue Manager's Default Sequence. The SetEnabled() command enables the Canvas Group, which will hide the portrait panel.
Code: Select all
{{default}}; SetEnabled(CanvasGroup, true, Portrait Panel)
- When you want to show the portrait panel, use this sequencer command in your dialogue entry node:
Code: Select all
{{default}}; SetEnabled(CanvasGroup, false, Portrait Panel)
There are two ways to do this:The_Kihng wrote: ↑Fri Aug 25, 2023 4:17 pm-Cancelled Conversations: I've found some settings related to cancelling the conversation when the player walks away. This works great on its own, but I'd also like to change a variable noting that the player walked away from the conversation, and have the NPC react to it, maybe with a bark at that moment or a different conversation when you next talk to them. I'm unsure how to trigger the variable change when this happens, unfortunately.
1. Without scripting, although somewhat awkward: Set the "walked away" variable to true at the start of the conversation. In the last dialogue entry node of the conversation, set the variable false.
2. With scripting: Make a subclass of DialogueSystemTrigger and use this in place of DialogueSystemTrigger. Override the StopActiveConversation() method. Example:
Code: Select all
public class MyCustomDialogueSystemTrigger : DialogueSystemTrigger
{
protected override void StopActiveConversation()
{
DialogueLua.SetVariable("walkedAway", true);
base.StopActiveConversation();
}
}
On the Dialogue Manager GameObject, tick the Input Device Manager component's Always Auto Focus. This will keep a response menu button focused (selected) when showing a response menu so you can navigate among them. The Dialogue System uses plain old Unity UI navigation to navigate menus. As long as your EventSystem works, you'll be able to navigate all Dialogue System UIs with the keyboard or joystick. If you want the player to be able to move during conversations, you'll need to map different Vertical and Horizontal inputs to your EventSystem than those used for player movement. If you want to disable player movement during conversations, see 07:00 of the Interaction Tutorial.The_Kihng wrote: ↑Fri Aug 25, 2023 4:17 pm-Keyboard Navigation: I'm sorry, I'm sure you get asked this a lot, but I just wasn't able to figure it out, even after looking it up. I want to navigate dialogue choices using the keyboard. I tried to enable this by adding the GUI Control script to the Response Menu Panel and enabling the Navigation option, but this didn't work. I think I'm close, however. The other issue is that the same keys used for movement would also be used for navigation, so I'd need the player to be able to move around (and potentially cancel the conversation if they wander off) until a choice comes up, which would prevent the player from moving while the choice remains on-screen.
Except for quests, it's not used for anything in particular. You can use it for whatever you like, or just ignore it. The one important thing it's used for is to hold information about quests. (Quests and items share the same data table because the Dialogue System uses the same data structure as a pro writing app called Chat Mapper.)
Add a typewriter effect to your subtitle text GameObject. If you're using UI Text, add a UnityUITypewriterEffect component. If you're using TextMesh Pro (see TextMesh Pro Support), use TextMeshProTypewriterEffect. If you're using Text Animator for Unity (see integration), it gives you options for very fancy typing.The_Kihng wrote: ↑Fri Aug 25, 2023 4:17 pmEdit: Just remembered. I'd also like to ask about text appearing one character at a time. I saw a setting for "Typewriter text"? Or something like that anyway. I wanted dialogue text to appear .. not all at once, if you understand. Is this possible, and if so, how? Also being able to adjust the speed of the text would be nice.
To adjust the speed, set the typewriter effect's Characters Per Second. You can also add RPG Maker-style control codes into your text to make it pause, appear immediately, etc.
If you're using continue buttons to advance the conversation, you may want the first click of a continue button to fast-forward the typewriter if it's still typing. The UI prefabs that ship with the Dialogue System behave like this. They use StandardUIContinueButtonFastForward components.
If you want to change the typewriter speed at runtime, see: How To: Adjust Typewriter Speed.
Re: Multiple Small Questions regarding the Dialogue System
Thank you very much! Most of this looks correct except for the variable one. This is my fault as I failed to actually mention the problem, haha. I already know how to raise the variable. That was fairly easy. The issue is that the variable is shared between all conversations at once, meaning if you talk to NPC A 3 times and then talk to NPC B, NPC B will act as if you've already spoken to them because they're using the same variable. Hence why I mentioned having an instance of the variable for each object- that was the part I couldn't figure out.
I'll work on implementing the rest of your advice. Thank you again for the quick reply!
Edit: I've almost finished implementing all of your suggestions. Strangely, though I can now navigate the responses with the arrow keys, neither one (I'm using two for this test) highlights at all. No clue why. I've also found that you can group variables (like the walking away one) by naming them Bar.var, Foo.var, and so on with var being your variable name. Interesting, but it doesn't solve my variable problem. There would be hundreds of interactable objects, and needing an individual variable in the list for each one would be way too difficult to keep track of, not to mention tedious.
I'll work on implementing the rest of your advice. Thank you again for the quick reply!
Edit: I've almost finished implementing all of your suggestions. Strangely, though I can now navigate the responses with the arrow keys, neither one (I'm using two for this test) highlights at all. No clue why. I've also found that you can group variables (like the walking away one) by naming them Bar.var, Foo.var, and so on with var being your variable name. Interesting, but it doesn't solve my variable problem. There would be hundreds of interactable objects, and needing an individual variable in the list for each one would be way too difficult to keep track of, not to mention tedious.
Re: Multiple Small Questions regarding the Dialogue System
Hi,
To investigate the navigation highlight issue, keep an inspector view on the EventSystem. At runtime, the bottom of the inspector will report which button is selected (i.e., has navigation focus). If it's reporting the correct button, check the Button component's Transition type. If it's set to Color, make sure the Selected and Highlighted colors are visually different from the Normal color. Also, you may also want to add a Deselect Previous On Pointer Enter component. When you mouse over a button, this component visually deselects the previously-selected button. (Surprisingly, Unity UI doesn't do this by default.)
For the variables, there are a few approaches you could take. The "no C# scripting" way would be to change the node's Script field. You don't have to define variables ahead of time in the Dialogue Editor's Variables section. For a character named Foo, you could set the first node's Script to:
That's admittedly verbose. But, wait, it can get even more verbose. You can use this same Script for all interactable objects:
When a conversation starts, the Dialogue System sets Variable["ConversantIndex"] to the name of the conversant as it appears in the Actor[] Lua table. So if the actor were "Foo", then Variable["ConversantIndex"] would be "Foo", which would make the line immediately above functionally the same as the one above it.
If you don't mind doing a little C# scripting, you could add a script to the Dialogue Manager that has an OnConversationStart(Transform) method. (Reference: Special Script Methods.) It could look like:
}[/code]
This will automatically create/increment a variable that has the same name as the value of Variable["ConversantIndex"]. No need for any Script fields in your conversations.
To investigate the navigation highlight issue, keep an inspector view on the EventSystem. At runtime, the bottom of the inspector will report which button is selected (i.e., has navigation focus). If it's reporting the correct button, check the Button component's Transition type. If it's set to Color, make sure the Selected and Highlighted colors are visually different from the Normal color. Also, you may also want to add a Deselect Previous On Pointer Enter component. When you mouse over a button, this component visually deselects the previously-selected button. (Surprisingly, Unity UI doesn't do this by default.)
For the variables, there are a few approaches you could take. The "no C# scripting" way would be to change the node's Script field. You don't have to define variables ahead of time in the Dialogue Editor's Variables section. For a character named Foo, you could set the first node's Script to:
Code: Select all
if (Variable["Foo"] == nil) then Variable["Foo"] = 1 else Variable["Foo"] = Variable["Foo"] + 1 end
Code: Select all
if (Variable[Variable["ConversantIndex"]] == nil) then Variable[Variable["ConversantIndex"]] = 1 else Variable[Variable["ConversantIndex"]] = Variable[Variable["ConversantIndex"]] + 1 end
If you don't mind doing a little C# scripting, you could add a script to the Dialogue Manager that has an OnConversationStart(Transform) method. (Reference: Special Script Methods.) It could look like:
Code: Select all
void OnConversationStart(Transform actor)
{
string conversantVariableName = DialogueLua.GetVariable("ConversantIndex").asString;
DialogueLua.SetVariable(conversantVariableName, 1 + DialogueLua.GetVariable(conversantVariableName).asInt);
This will automatically create/increment a variable that has the same name as the value of Variable["ConversantIndex"]. No need for any Script fields in your conversations.
Re: Multiple Small Questions regarding the Dialogue System
So it turns out that the highlight is indeed working, but it is *extremely* hard to see. Even with the colors set to complete opposite ends of the spectrum, it can be hard to tell which is highlighted. Now that I know it's working though, I can tinker with it.
I'd like to add a little animated pointer to the highlighted option. I think that'd help a lot, and I already have one on hand. I already added a different one to the continue button, but this would be a bit more complicated as it has to move to the highlighted option, no?
I like all of the options for the variables. Verbose is often better! If I choose the C# option, will I have to add it to the assembly thing? Assemblies hurt and confuse me and I'd rather avoid that, unless it's super simple. I spent a couple hours yesterday screaming at the asset that imports the .asmdef files thinking it WAS the .asmdef file and I couldn't figure out why I couldn't make an assembly reference with it.... To be fair, the name was very misleading. (I was trying to reference a namespace in one of the assembly scripts and it didn't like that. Eventually I just made the reference to the assembly in the namespace instead and it worked. Go figure.)
I'd like to add a little animated pointer to the highlighted option. I think that'd help a lot, and I already have one on hand. I already added a different one to the continue button, but this would be a bit more complicated as it has to move to the highlighted option, no?
I like all of the options for the variables. Verbose is often better! If I choose the C# option, will I have to add it to the assembly thing? Assemblies hurt and confuse me and I'd rather avoid that, unless it's super simple. I spent a couple hours yesterday screaming at the asset that imports the .asmdef files thinking it WAS the .asmdef file and I couldn't figure out why I couldn't make an assembly reference with it.... To be fair, the name was very misleading. (I was trying to reference a namespace in one of the assembly scripts and it didn't like that. Eventually I just made the reference to the assembly in the namespace instead and it worked. Go figure.)
Re: Multiple Small Questions regarding the Dialogue System
Hi,
Regarding asmdefs, the Dialogue System doesn't use them by default, but you can import the DialogueSystemAssemblyDefinitions.unitypackage file located inside the Dialogue System's Scripts folder if you want them. The Dialogue System is, however, inside a special folder named Plugins. (See: Special folders.) Unity compiles scripts inside the Plugins folder before any scripts that are outside of Plugins, and scripts inside Plugins have no access to scripts outside of Plugins. This two-stage compilation process lets Unity skip recompiling Plugins unless a script inside Plugins has changed. This speeds up compilation since you can modify your own scripts that are outside of Plugins, and Unity only needs to recompile your scripts without having to also recompile Plugins. Your scripts that are outside of Plugins can access scripts in Plugins.
For the animated pointer, I recommend adding an animated pointer to all response buttons. If you're using the StandardUIMenuPanel's Button Template, which instantiates buttons at runtime as needed for each menu, you'd just add the animated pointer to the response button template. Change the Button component's Transition dropdown to Animation. This will set up the button to play animation clips when it changes state from normal to highlighted, selected, etc. Use Unity's Animation window to edit the animations. Animations in Unity can animate any property. In this case, configure the Normal animation to deactivate the animated pointer GameObject. Configure the Selected and Highlighted animations to activate and animate the pointer.
Regarding asmdefs, the Dialogue System doesn't use them by default, but you can import the DialogueSystemAssemblyDefinitions.unitypackage file located inside the Dialogue System's Scripts folder if you want them. The Dialogue System is, however, inside a special folder named Plugins. (See: Special folders.) Unity compiles scripts inside the Plugins folder before any scripts that are outside of Plugins, and scripts inside Plugins have no access to scripts outside of Plugins. This two-stage compilation process lets Unity skip recompiling Plugins unless a script inside Plugins has changed. This speeds up compilation since you can modify your own scripts that are outside of Plugins, and Unity only needs to recompile your scripts without having to also recompile Plugins. Your scripts that are outside of Plugins can access scripts in Plugins.
For the animated pointer, I recommend adding an animated pointer to all response buttons. If you're using the StandardUIMenuPanel's Button Template, which instantiates buttons at runtime as needed for each menu, you'd just add the animated pointer to the response button template. Change the Button component's Transition dropdown to Animation. This will set up the button to play animation clips when it changes state from normal to highlighted, selected, etc. Use Unity's Animation window to edit the animations. Animations in Unity can animate any property. In this case, configure the Normal animation to deactivate the animated pointer GameObject. Configure the Selected and Highlighted animations to activate and animate the pointer.
Re: Multiple Small Questions regarding the Dialogue System
That's odd. I wasn't able to get the Dialogue System to recognize the New Input System's InputActionAsset (I think it's called that?) until I made an assembly reference asset and made a direct register in the code of
If what you're saying is correct (and you have been every time so far! You really know your stuff. :D) then the Assembly Reference was unnecessary? The whole plugins folder thing explains why I couldn't reference my namespace from your scripts though, so thank you for telling me that.
Regardless, I should just be able to add the variable script to the Dialogue Manager object, no fancy steps needed?
As for the animated pointer, I will try that. Thank you for the detailed advice. Hopefully I won't need anymore help after this. Don't want to take up too much of your time, haha.
Code: Select all
PixelCrushers.InputDeviceManager.RegisterInputAction("InteractGeneric", playerInputActions.Player.InteractGeneric);
Regardless, I should just be able to add the variable script to the Dialogue Manager object, no fancy steps needed?
As for the animated pointer, I will try that. Thank you for the detailed advice. Hopefully I won't need anymore help after this. Don't want to take up too much of your time, haha.
Re: Multiple Small Questions regarding the Dialogue System
You're correct. You need to use InputDeviceManager.RegisterInputAction() for the Dialogue System to be able to recognize an input action.The_Kihng wrote: ↑Sat Aug 26, 2023 12:03 pmThat's odd. I wasn't able to get the Dialogue System to recognize the New Input System's InputActionAsset (I think it's called that?) until I made an assembly reference asset and made a direct register in the code ofIf what you're saying is correct (and you have been every time so far! You really know your stuff. ) then the Assembly Reference was unnecessary? The whole plugins folder thing explains why I couldn't reference my namespace from your scripts though, so thank you for telling me that.Code: Select all
PixelCrushers.InputDeviceManager.RegisterInputAction("InteractGeneric", playerInputActions.Player.InteractGeneric);
That's correct, too.
I'm here to help, so if you have any questions please feel free to ask.
Re: Multiple Small Questions regarding the Dialogue System
I was hoping to avoid this, but it seems I'm quite stuck. I just spent a good 4 hours getting the animated cursor to work properly. It now successfully works! (My problem was that I tried doing it through the Animator rather than the Animation window.) However, the cursor is slow to disappear after switching to another option, allowing, if briefly, for multiple cursors at once. I tried adjusting the speed settings of the Animator Controller, but it didn't seem to have an effect.
I also implemented the variable script you wrote... and now I can't talk to anyone. It seems there's something wrong with the conditional. Here it is:
I also tried null instead of 0 just in case but that didn't help sadly. I then tried adding a line to the script to print the value of ConversantIndex, but it did nothing. Which is odd.
I know the Conversation is being triggered because the console says it is. It's just rejecting every conditional.
Not sure what's going on here, honestly.
I also implemented the variable script you wrote... and now I can't talk to anyone. It seems there's something wrong with the conditional. Here it is:
Code: Select all
Variable["ConversantIndex"] == 0
Code: Select all
Debug.Log(DialogueLua.GetVariable(conversantVariableName).asInt);
Not sure what's going on here, honestly.
Re: Multiple Small Questions regarding the Dialogue System
In your animator controller, inspect the transition arrows. UNtick Has Exit Time. Otherwise it will wait for the animation to finish a complete loop before transitioning.
Variable["ConversantIndex"] will be the name of the conversant, modified according to these rules so it can be an index in the Lua Actor[] table. An index in a Lua table is like a key in a C# Dictionary.The_Kihng wrote: ↑Sat Aug 26, 2023 10:56 pmI also implemented the variable script you wrote... and now I can't talk to anyone. It seems there's something wrong with the conditional. Here it is:Code: Select all
Variable["ConversantIndex"] == 0
If the conversant's Name is "Bob", the ConversantIndex will be "Bob".
If the conversant's Name is "Bob the Builder", the ConversantIndex will be "Bob_the_Builder".
Note: In contrast, Variable["Conversant"] will be conversant's display name. If you've set the conversant's Name to "Bob", ticked Use Display Name, and set Display Name to "Bob the Builder", then Variable["Conversant"] will be "Bob the Builder" and Variable["ConversantIndex"] will be "Bob". If you haven't ticked Use Display Name, both values will be "Bob".