UMG: UNDERTALE styled dialogue box.

Alright, so I usually seem to be competent with blueprint for the most part, but I’m kinda stumped with this. (Also, I have close to zero experience with UMG and am having trouble understanding some of the guides.)

Basically: I have a simple dialogue system for my NPCs, and the dialogue is currently output to the log without any UI. Essentially what I’m trying to do is re-create the dialogue system from UNDERTALE, to give you an idea of how it functions.

Example:
9qyN3ae.png

Unfortunately, I can’t even seem to figure out the simple task of accessing the UMG widget’s variables from inside my NPC blueprint (so I can change the dialogue box’s text), let alone the actual design and layout of this thing in the UMG designer. If anybody would be able to point me in the right direction or give me some tips here, that would be great.

[HR][/HR]
While just the basics would help me get a good starting point, here’s the list of requirements I would hopefully like to figure out for the final dialogue system (listed in order of highest to lowest priority):

  1. String from NPC blueprint is displayed one character at a time, playing a sound file with each character.

  2. The ability to answer certain dialogue prompts with a pointer and arrow keys which would send a value back to the NPC to decide which dialogue path to continue on.

  3. The ability to pause at certain words and delay the rest of the message. (Example: The message “Hello! [0.5s delay] How are you doing?” displays automatically in a single text box.)

  4. Animated character portrait on the left side. (Does UMG support gifs? Should it just be two frames [mouth open/closed] switched back and forth programmatically?)

I feel like if somebody can help me get started on this thing, I should be able to figure out a lot of these things on my own. Thanks to anyone who can help out!

UPDATE: Okay, so turns out the reason I couldn’t access the text bind variable was because I had to expose and make it editable, which I neglected to do before. Now I can get the text displaying. I’ll continue trying to figure this out myself, if anybody has any ideas or suggestions I would love to hear from you!

UPDATE 2: Figured out how to loop the array of individual characters from the string into the UMG text widget, but I now realize I can’t use a ForEachLoop because you can’t use a delay node inside of loop iterations. Not sure how to go about doing this.

Edit 3: Got a manual loop going, works fine. I also managed to manually add pauses to the text by splitting up the strings where the pauses would be, then putting a delay between them and appending the rest of the text to the text that is being written to the text widget. Now I gotta figure out how to make it so you can press a button to skip the typing and just display all the text.

I’m not sure how to do this, but STAY DETERMINED.

Thank you, haha. I certainly will.

Also, another update: I got the skip text functionality almost working but my code started to become too unorganized and bloated, and then things stopped working and I couldn’t debug it properly because it was such a mess. I probably won’t be able to work on this much for the next few days due to school work, but if anybody would like to input their ideas please do so! I appreciate it!

i got some issue trying to cast blueprint from a UMG widget.
the only way was to create my variable in a class blueprint (character, pawn, gamemode) and cast to my UMG

What I usually do in situations like this is create a widget, and give it several variables relating to how it could possibly be set up (e.g. a Texture2D reference for the image of the speaking character, a text variable for the name of that character, a text variable that includes the actual text of the bubble, a bool for whether the face should appear to the left or the right of the text itself, etc.)

Then I’d set up a Custom Event in the widget called “Pass In Dialogue”. I would give it inputs that correspond to all my variables I just made above, and configure it to Set those variables to its input values whenever called.

Now, whenever I want to generate dialogue (via the level BP, some NPC’s BP, whatever) I call Create Widget with the class being my Dialogue Widget. I then immediately grab the output of that (the widget referece) and call Pass In Dialogue to send it all of the relevant info regarding this piece of dialogue. Then, Add to Viewport.

I would suggest finding a way to have removing itself from the viewport be something included in the dialog box itself (e.g. when the player presses a button or whatever)

For roll-out text, you are doing it the SUUUUUPER complicated way. Here’s a far simpler way: Create a Timer, set it to Loop, and give it a time near 0.25 s or so. That Timer should simply increment an Int variable by +1 (we’ll call it TextProgress) Call it to start whenever the dialogue widget is created.

In the Get Text function of the actual text box in the widget itself, rather than just reading the Pass In Dialogue text variable, it should take that variable, convert it to a string, run a Left Chop on that string (using TextProgress to feed the Int), then convert it back to Text to display it (note: since this is purely cosmetic, losing the Text localiization is okay, we’d just need to handle localization BEFORE doing this roll-out effect).

Now, every 0.25 seconds, your passed in string will get one character longer. You can obviously speed this up if you like. The timer can also do other things like play a tiny sound cue for each added letter (pretty common effect). It can handle playback adjustments too: whenever a key is pressed, you retrigger the timer at 0.1s looping (or whatever) and then back to 0.25 when that key is released.

You can also check the Int of TextProgress against a Len called on the initial Text variable (converted to string, of course) to see how close you are to the END of the text… At which point you can branch the behavior of the text speedup button to destroy the dialogue box, go to the next page, whatever.

Thanks for the input! I’ve actually gotten to the point that it’s completely functional. My roll-out text system is basically the same as what you described, except instead of a timer it’s just a branch statement with an incrementing index value instead. It works for my purposes pretty well.

I’ve decided against using character portraits so I won’t be worrying about that.

Unfortunately, due to the fact that I wanted the ability to add pauses mid-string means things got a little complicated with the way I’m handling my dialogue strings. The only way I’ve figured out to handle it is having a string with the full text of what the character says (so if the player presses the skip button, it will cancel the roll-out event and display the full text from that string), and then whenever I want there to be a pause in the dialogue, I cut the string at the pause, put a delay, then append the text after the pause to the text roll-out event. Like so:

The branch node is there to check if the player is still on the specific branch of dialogue and haven’t skipped to the next one already. If the player did, it won’t continue printing the rest of the dialogue past that delay.

My biggest concerns with the way I’m handling this are of course, localization, and also just the fact that this is going to start becoming a pain to manage when I get more and more lines of dialogue in the game. I know absolutely nothing about localization. If I even get the point that this becomes a finished product, I doubt it will be even remotely big enough that I would need to worry about something like that, but I guess it’s better to be on the safe side? Not sure how I should be able to condense that down though so that it won’t be a pain in the ***. Thanks again for the help.