New and Lost :(

Announcements, support questions, and discussion for the Dialogue System.
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

New and Lost :(

Post by Raelyr »

Hello, I've recently downloaded the trial version of dialogue system for unity and am still trying to make sure it does everything I'm looking for. I got the basics up and running and that part is great, even did some editing of the UI! Now I'm looking at performing actions during the dialogue. I got some basic stuff done, like making it enable/disable gameobjects. But I want to do more, and got lost trying to read through the documentation on some of the more complex stuff.

For example, what I want to do now is make it change the name of one of the actors from 'Stranger' to their proper name after the actor introduces themselves. Can someone please point me in the right direction to do this?
User avatar
Tony Li
Posts: 21080
Joined: Thu Jul 18, 2013 1:27 pm

Re: New and Lost :(

Post by Tony Li »

Hi,

Thanks for checking out the Dialogue System!

Here's an example scene: DiscoverNameExample_2017-08-12.unitypackage

To set it up, I configured the actor to use a Display Name, initially set to "Stranger":

Image

When the player learns the stranger's name, we want to set Display Name to something different. To do this, I wrote a small Lua function and used it in the Script field:

Image

The Lua function is in a script that I added to the Dialogue Manager. I had to write the Lua function to tell the Dialogue System to start using the new display name in the active conversation. If that weren't necessary -- that is, if you only needed to start using the new name in future conversations -- you could have skipped the Lua function and just set Script to:

Code: Select all

Actor["Mephistopheles"].Display_Name = "Mephistopheles"
The Lua function is in the example package above. I'll paste the code here, too:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

/// <summary>
/// Add this to the Dialogue Manager. It adds a Lua function that you can use in your
/// dialogue entries' Script fields:
/// 
/// ChangeActorName(actorName, newDisplayName)
/// </summary>
public class ChangeActorNameLua : MonoBehaviour
{

    void OnEnable()
    {
        // Make the function available to Lua:
        Lua.RegisterFunction("ChangeActorName", this, SymbolExtensions.GetMethodInfo(() => ChangeActorName(string.Empty, string.Empty)));
    }

    void OnDisable()
    {
        // Remove the function from Lua:
        Lua.UnregisterFunction("ChangeActorName");
    }

    public void ChangeActorName(string actorName, string newDisplayName)
    {
        if (DialogueDebug.LogInfo) Debug.Log("Dialogue System: Changing " + actorName + "'s Display Name to " + newDisplayName);
        DialogueLua.SetActorField(actorName, "Display Name", newDisplayName);
        if (DialogueManager.IsConversationActive)
        {
            var actor = DialogueManager.MasterDatabase.GetActor(actorName);
            if (actor != null)
            {
                var info = DialogueManager.ConversationModel.GetCharacterInfo(actor.id);
                if (info != null) info.Name = newDisplayName;
            }
        }
    }
}
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

Re: New and Lost :(

Post by Raelyr »

Thanks so much for your help! I was able to get this working and it does exactly what I wanted. I can also see how to use this to perform other actions in the future as well. Though, can I use something like this to, for example, end a conversation and change scenes? IE if the player's responses lead them to accept a teleportation spell to somewhere else? Or actually I think mechanically it might be something like - can we store the 'next scene' in a variable that can be altered throughout the conversation, and move the player there when the conversation ends? Then just end the conversation when they accept the teleport.

Also I was working on text input and I have one that functions when the NPC asks what the player's name is. Is there a way I can access what they put in and store it in a script on the player's gameobject?

I'm also having trouble introducing a third party to a conversation. For example, my player and an NPC are talking and a wild animal comes by and says 'Grr!'. I added a third actor to the conversation database, and made sure the name of the actor and the gameobject match. When the node the animal should be 'saying' comes up, it enables the Sprite Renderer like I asked it to, but it skips the animal's line in the conversation! Did I miss a step somewhere?
User avatar
Tony Li
Posts: 21080
Joined: Thu Jul 18, 2013 1:27 pm

Re: New and Lost :(

Post by Tony Li »

Raelyr wrote:Thanks so much for your help! I was able to get this working and it does exactly what I wanted. I can also see how to use this to perform other actions in the future as well. Though, can I use something like this to, for example, end a conversation and change scenes? IE if the player's responses lead them to accept a teleportation spell to somewhere else? Or actually I think mechanically it might be something like - can we store the 'next scene' in a variable that can be altered throughout the conversation, and move the player there when the conversation ends? Then just end the conversation when they accept the teleport.
Even easier, use the LoadLevel() sequencer command. If you want it to happen at the end of the conversation, just add it to the dialogue entry node that ends the conversation. This command accepts an optional spawnpoint, which is the name a GameObject in the new scene where the player should appear. For example:
  • Dialogue Text: "Okay, teleport me to Mordor."
    Sequence:

    Code: Select all

    LoadLevel(Mordor,Black Gates)
Raelyr wrote:Also I was working on text input and I have one that functions when the NPC asks what the player's name is. Is there a way I can access what they put in and store it in a script on the player's gameobject?
The TextInput() sequencer command stores the result in a Dialogue System Lua variable. Your script can call DialogueLua.GetVariable() to get the value. For example:
  • Dialogue Text: "What's your name?"
  • Sequence:

    Code: Select all

    TextInput(TextFieldUI, Name, playerName)

Code: Select all

using PixelCrushers.DialogueSystem;
...
var myName = DialogueLua.GetVariable("playerName").AsString; 
One thing to keep in mind is that the Conditions field is evaluated one level ahead. (This is necessary to support certain continue button modes.)
Raelyr wrote:I'm also having trouble introducing a third party to a conversation. For example, my player and an NPC are talking and a wild animal comes by and says 'Grr!'. I added a third actor to the conversation database, and made sure the name of the actor and the gameobject match. When the node the animal should be 'saying' comes up, it enables the Sprite Renderer like I asked it to, but it skips the animal's line in the conversation! Did I miss a step somewhere?
Try adding this line to your Sequence:

Code: Select all

Delay({{end}})
(Separate sequencer commands with semicolons, like with C# code.)

The Dialogue System displays each line for as long as its Sequence lasts. The SetActive() sequencer command runs immediately, so your line is probably appearing and disappearing in the same frame. The Delay({{end}}) command makes the sequence delay for a duration based on the length of the Dialogue Text, giving you a chance to see it.
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

Re: New and Lost :(

Post by Raelyr »

Thanks so much for your help! I have it almost exactly how I want now.

The last thing I want to do is make it so that if (None) is the person speaking it doesn't try to display the portrait or name...I've done some poking around in the UI panels but I'm not sure how to do that.
User avatar
Tony Li
Posts: 21080
Joined: Thu Jul 18, 2013 1:27 pm

Re: New and Lost :(

Post by Tony Li »

Raelyr wrote:The last thing I want to do is make it so that if (None) is the person speaking it doesn't try to display the portrait or name...I've done some poking around in the UI panels but I'm not sure how to do that.
You're really finding all the edge cases! :-)

The easiest, non-scripting solution is to create an actor such as "Narrator" that specifies which UI elements to use:

1. Inspect the dialogue UI, and tick Find Overrides:

Image

2. Create a GameObject named "Narrator". Or, if you want to name the GameObject differently, add an Override Actor Name component to it, and set the Override Name to "Narrator". You can make it a child of the Dialogue Manager to bring it along with you as you change scenes.

3. Add an Override Unity UI Dialogue Controls component to Narrator. Then assign the UI elements that you want to use for the Narrator (panel, text line), and don't assign the ones you want to hide (portrait image, portrait name ):

Image

At a minimum, you must assign the Panel field.

You can also use this technique to make actors use completely different UI panels. For example, the animal might show "Grr!" in a world space canvas above its head, instead of the regular dialogue panel.
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

Re: New and Lost :(

Post by Raelyr »

Tony Li wrote:You're really finding all the edge cases! :-)
The package costs a lot! I want to make sure it does everything I needed before buying, haha.

And it seems like it does! I'm going to keep poking around with it probably the rest of the day, but I think that's all the weird circumstances I had in mind, so great!
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

Re: New and Lost :(

Post by Raelyr »

Okay, just a couple more questions...probably.

First, with the player responses menu, the scrolling through it is reeeeeeeeally slow. How would I change how quickly they can scroll through the options?

That's the easy one. My other question is less mechanical and more about design. The game that I'm working on is 2D and basically flips between a 'story mode' and 'combat mode'. It'll play a little like a deck-building game, but instead of cards you play as a newly-minted wizard who collects 'elements' you can string together each round to cast spells. Story mode is the main place I'll be using dialogue system, of course. In story mode, you're presented with a first-person view of the scene background, and any characters involved in the current scene. The dialogue is really important because you'll make decisions that unlock new elements, companions, 'assets', and so on.

For my 'intro' scene where I'm testing and trying new things, I made the dialogue manager run the 'intro' conversation on scene start. I noticed you mentioned before that it's probably a good idea to make the dialogue manager dontdestroyonload. But if I do that, can I make it load the conversation specific to the current scene? Also, will it get confused with various characters being removed and added? Would it be a better design to create a new dialogue manager and database for each scene?

Oh! And on a related note - can I use the alerts system without really creating a new conversation? For example, in combat mode if the player tries to string together too many elements, can I use dialogue system's alerts to tell them to knock it off?
User avatar
Tony Li
Posts: 21080
Joined: Thu Jul 18, 2013 1:27 pm

Re: New and Lost :(

Post by Tony Li »

Raelyr wrote:The package costs a lot! I want to make sure it does everything I needed before buying, haha.
Fair enough. :-)
Raelyr wrote:Okay, just a couple more questions...probably.
First, with the player responses menu, the scrolling through it is reeeeeeeeally slow. How would I change how quickly they can scroll through the options?
"It depends" is the worst answer, but... it depends. If you're using Unity UI (for example, the generic dialogue UI in the default Dialogue Manager prefab) and talking about keyboard/gamepad scrolling, inspect the EventSystem and decrease the Repeat Delay. If you're talking about scrolling with the mouse in a scroll rect, inspect the Scroll Rect and increase the Scroll Sensitivity. In other words, if you're using Unity UI then it's all controlled by Unity UI, not by the Dialogue System.

If you're using legacy Unity GUI, find the panel that holds the responses. Expand the Navigation foldout. Decrease the Axis Repeat Delay (for key/gamepad) and/or increase the Mouse Wheel Sensitivity.

If you're using another GUI system, such as NGUI, it's usually up to the GUI system.
Raelyr wrote:That's the easy one. My other question is less mechanical and more about design. The game that I'm working on is 2D and basically flips between a 'story mode' and 'combat mode'. It'll play a little like a deck-building game, but instead of cards you play as a newly-minted wizard who collects 'elements' you can string together each round to cast spells. Story mode is the main place I'll be using dialogue system, of course. In story mode, you're presented with a first-person view of the scene background, and any characters involved in the current scene. The dialogue is really important because you'll make decisions that unlock new elements, companions, 'assets', and so on.

For my 'intro' scene where I'm testing and trying new things, I made the dialogue manager run the 'intro' conversation on scene start. I noticed you mentioned before that it's probably a good idea to make the dialogue manager dontdestroyonload. But if I do that, can I make it load the conversation specific to the current scene? Also, will it get confused with various characters being removed and added? Would it be a better design to create a new dialogue manager and database for each scene?
The Dialogue Manager GameObject (actually the DialogueSystemController script on it) maintains the Lua environment that contains the current values of all variables. If you use a new Dialogue Manager, you'll lose those values. If that doesn't matter for you, then you can untick Dont Destroy On Load.

However, it sounds like you can just add another GameObject (separate from the Dialogue Manager) to the 'intro' scene that has a Conversation Trigger set to OnStart.
Raelyr wrote:Oh! And on a related note - can I use the alerts system without really creating a new conversation? For example, in combat mode if the player tries to string together too many elements, can I use dialogue system's alerts to tell them to knock it off?
Sure! You might also want to inspect the dialogue UI's Alert foldout and tick Queue Alerts. This shows them one after the other, instead of allowing the most recent alert to immediately supercede any previous alerts. That's just a design decision on your part, though.
Raelyr
Posts: 19
Joined: Sat Aug 12, 2017 11:47 am

Re: New and Lost :(

Post by Raelyr »

Easy fixes to 'big problems'...excellent. It was the scroll sensitivity on the one, and I guess I just didn't think of putting the conversation starter on a different object for the other, haha. I just followed the step-by-step. But now I've set it up so that every story mode scene has a 'scenemanager' object which can handle its appropriate conversation. So all set! Thank you again!

One last (lol) question did come up though. For the textinput I have to collect the player's name, it works - it even stores the name and I can get to it fine so that part's great. But for some reason when it first displays the input field, it has 'nil' in there instead of being empty and displaying the placeholder text. Any idea why?

Oh! I lied again...just one more question! If I'm using a script to change the character name like we discussed before, and then, say, the player saves the game and loads it later, will it remember the 'new' name or revert to 'Stranger'?
Post Reply