General Use Case.
All of my widgets generally follow the same pattern due to using a letter by letter popup system, below you can see what the whole thing looks like. (This is one example of many widgets)
You might have noticed that this is made up of 3 copies of a single block of code, this is because it makes more sense to change the text appearing for the next sentence rather than change to a different widget. This is more efficient, concise and easier to understand.
Event construct just means when the widget is created in the blueprints. This then goes to getting an actor of class, in this case the player blueprint. Since there's only one of these blueprints at a single time, there's no reason to be more concise.
Using the event construct, the maximum walk speed of the character is set by getting the character movement component from the target blueprint and simple using a set max walk speed node with 0. This is equivalent to saying that the player never moves or even rotates.
The code then sets a timer by event with looping selected. The custom event used for this is called set text to match it's purpose. The time between loops is just called type speed, a float variable set to 0.075. This is a 7% of a second time gap between a new letter being added to the display and is what I found to be quite a good speed.
The pink plugin for the set display text node is where the code on the left goes into. The input text is a string variable that goes into a get character array from string node. From here, an integer variable named index is used to find the position of the letter to add before appending it to the display text. At the start of the widget, the display text is set to nothing. This means that nothing is ever added to the display text but the input text, letter by letter as is intended for atmospheric effect.
The display text being set then leads to setting the actual textbox in the graph (display area) of the widget. This updates the actual display by setting it to match the display text variable, first converted to a text variable from a string to allow the SetText to operate properly.
The index then is set with a ++ node. This is a programmers abbreviation of "add one to this variable please". This just means that when the event loops, the index will go one higher, meaning the next letter in the input text variable will be added as the code will read the next variable in the array rather than the same one over and over.
Eventually, the index will go higher than the character count within the array formed by the input text. This would normally cause a crash or no text to be added, as well as meaning this event never ends. To avoid this, we simply check if the index (the character number we want to get from the array) is lower or higher than the amount of index positions in the input text. If it's higher, then make sure to end the event as the full text has been displayed, if not then it just keeps looping until it's finished.
Here you can see where the branch is. If the index + 1 is equal to the amount of characters in the array, then it stops the loop by invalidating the timer by handle.
There is then a 1 second delay to ensure the player reads the text on the screen before the code resets the index to it's starting value of 0, the display text to nothing and the input text to the next sentence.
The code then repeats what I have already talked about until it reaches the end.
The delay is slightly longer at the end, allowing the player to recognise it's over. Before removing the widget from the player screen, the main character blueprint is gotten by the get actor of class node before setting the max walk speed to 400. This is the value on game start and by changing it back to the usual value, we can let the player start moving again to keep playing the game.
Specific Change Case.
When it comes to the conversation with the monster at the door, the code is slightly more complex. At the end, the widget begins an event in the main character blueprint to create another widget.
As you can see, the only real change is casting to the main character (specifically the character with index 0) before setting off a custom event inside the blueprints.
It's genuinely this simple. The event set off by the first widget will set off an event in the main character to create the next widget and add it to the player viewport, from there the widget just does what I've already said other than changing the next event it sets off.
(Shown throughout)
Conclusion
In conclusion, I think I did quite well with making the widgets. The only issue I have is that I could have found a way to loop the body for doing the letter by letter code, meaning that I could have avoided the long strings of code I had in each widget just for multiple sentences. In the future, I would definitely try to implement one of these systems, as without it the code looks messy and is really unoptimised.