I recently started work on the dialogue system for my game, and making the text box was the first step. I’ve noticed that when I write scrolling text to the text box (through a modified For Each loop), the text will suddenly jump to the next line when the word gets too long, which is really unseemly and makes reading the text rather difficult. Is there a way, either through Blueprint or C++, to make the text wrap when the amount of space left wouldn’t be enough for the next word?
The UMG Widget Text Box (Multi-Line) has a wrapping which is enabled by default.
It is called “Auto Wrap Text” in its Details Panel.
Yes, that is what I’m using, and that is what is causing the issue. The way I scroll the text, one letter at a time, means that if a word has not finished displaying and its next letter would go past the text box, then the word will jump down to the next line because of the wrapping, like it would in a text editor, which isn’t something that happens in most games.
If I understand you correct you are adding one character after another into the text box? This should be the root of your problem. Preprocess your text and add it word by word and the text box should be able to do the wrapping correctly.
Adding the characters one by one is the only way I’ve found to make the text scroll like you would see in a RPG. Adding it word by word would fix the problem, but I wouldn’t have the scrolling effect.
Ah now i see your problem. Are you using the blueprint or the c++ version of the text box?
Blueprint, I just used the widget available in the UMG Designer. I’m not very knowledgeable when it comes to C++, and I’m in the prototyping stage so I figured Blueprint would be sufficient.
Could you provide me with a screenshot of your blueprint to add the letters to the text box?
Okay i came up with a solution:
I created a Widget with following setup:
- The multi line text box
- The text to print as string array one word per element
- width of the textbox in chars before the linebreak (you have to try it out to find the correct number, in my textbox the correct value was 35
- position to print the next word in the current text box line (to test for line wrap)
- newline char (can be created by pressing shift+enter in the string field)
- space character
This are the helper functions I use:
And here is the event graph in the widget:
To summarize my algorithm I test every word to print if it would create the unwanted line wrap in the text box. If it would be the case I print a newline char before it. Then I print the word char by char with a delay through the modified foreach loop in a similar way you do.
I hope this helps. If you cant understand my blueprints just feel free to ask. Greetings
No problem! Getting this to work was a nice exercise for me as well
That works really well! Thank you for your help!
Your method is not good, because it is based on characters count (characters have different size actually). So you need a way to measure a real width of text in UMG. Here’s my function, if anyone need it:
FString UGameFunctionLibrary::makeWrappedText(FString InString, float size, UTextBlock* textBlock) //UTextBlock* textBlock
{
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
int last_space = -1;
int last_newline = -1;
FString testLine;
for (int i = 0; i < InString.Len(); i++) {
if (InString[i] == ' ') {
testLine = InString.Mid(last_newline + 1, i - last_newline);
if (FontMeasure->Measure(testLine, textBlock->Font).X > size) {
if (last_space >= 0) {
InString[last_space] = '\n';
last_newline = last_space;
}
else {
InString[i] = '\n';
last_newline = i;
}
}
last_space = i;
}
}
return InString;
}