Hey Community,
I’m in abit of a stump for this particular WrapText method that I am working on; i’d like to be able to see a Char’s pixel position on the screen that is part of an FString.
Right now I am able to get the TextSize by using GetTextSize - however it ignores new lines which is not good for what I need.
Is there a method at all that exists in UE4 to help with this? Thanks!
Part Two!
So, I don’t think finding the Char Position is going to do any good after further researching. I came across something interesting however:
https://forums.unrealengine.com/development-discussion/c-gameplay-programming/79203-fcanvastextitem-with-text-wrapping
Unfortunately I haven’t been able to get the code to wrap - even in any kind of testing condition. These methods are being used inside of the DrawHUD Method - so it’s called every tick. Can someone explain to me why this isn’t wrapping the text? Thanks in advance!
FCanvasTextItem ConversationText(FVector2D::ZeroVector, FText::FromString(CurrentDialogueLine), ConversationFont, FLinearColor::White);
ConversationText.Scale = FVector2D(ScaleUI * 1.4, ScaleUI * 1.4);
ConversationText.EnableShadow(FLinearColor::Black, FVector2D(1.0, 1.0));
ConversationText.SetColor(FLinearColor(1.0, 1.0, 1.0, ConversationBox_Alpha));
ConversationText.Position = FVector2D(
HUD_ConversationBox_Pos.X + HUD_ConversationBox_Size.X * 0.05,
HUD_ConversationBox_Pos.Y + HUD_ConversationBox_Size.Y * 0.05);
FCanvasWordWrapper wrapper;
FTextSizingParameters params;
TArray<FWrappedStringElement> lines;
params.DrawFont = ConversationFont;
params.DrawX = 0;
params.DrawXL = 25;
params.DrawY = 0;
params.DrawYL = 25;
params.Scaling = FVector2D(ScaleUI * 1.4, ScaleUI * 1.4);
UCanvas::WrapString(wrapper, params, 0, *ConversationText.Text.ToString(), lines);
Canvas->DrawItem(ConversationText);
Update: I haven’t been able to find the answer to this yet. If anybody knows how to use the Word Wrapper with C++ then please feel free to chime in.
I wasn’t able to figure out how to use the method the engine provides but instead I made my own that works perfectly. I’ll post it up to help anybody else who may need it!
Some essentials:
Run this method first under the DrawHUD method - it needs to constantly be in use. Aka a Tick.
void ASoulMachineMyHUD::GetAndSetTextBoxSize()
{
//Variable Descriptions...
/*
* 1) Text Letter Iteration is a global integer that is used for a 'single' letter at a time that I use for my project.
* 2) Create an FVector2D and the method GetTextSize will assign the .X and .Y of it.
*/
GetTextSize(TemporaryString.Mid(0, TextLetterIteration), ConversationText_Size.X, ConversationText_Size.Y, ConversationFont, ScaleUI * 1.4);
//Basic variable assignment that we'll use for later. No point in being in this method though.
float ConversationBoxFullSizeX = HUD_ConversationBox_Pos.X + HUD_ConversationBox_Size.X;
float ConversationTextFullPosX = (HUD_ConversationText_Pos.X + ConversationText_Size.X);
float ConversationTextFullPosY = HUD_ConversationText_Pos.Y + ConversationText_Size.Y;
}
void ASoulMachineMyHUD::WordWrapFunc()
{
//TemporaryString is a Global FString
//CurrentDialogueLine is a Global FString
//TArray<FString> WordWrapString is a global Array
float ConversationBoxFullSizeX = HUD_ConversationBox_Pos.X + HUD_ConversationBox_Size.X;
float ConversationTextFullPosX = HUD_ConversationText_Pos.X + ConversationText_Size.X;
float ConversationTextFullPosY = HUD_ConversationText_Pos.Y + ConversationText_Size.Y;
if (TextLetterIteration < TemporaryString.Len())
{
TextLetterIteration++;
}
else
{
for (int i = 0; i < WordWrapString.Num(); i++)
{
CurrentDialogueLine += WordWrapString[i];
}
CurrentDialogueLine += TemporaryString;
GEngine->AddOnScreenDebugMessage(-1, 5.0, FColor::Cyan, FString::FString("Text is wrapped!"), true);
SetHasFinishedTextWrappin(true);
TextLetterTimerFuncCall(TextIterationSpeed, true);
GetWorldTimerManager().ClearTimer(TextLetterWrapMethodTimer);
}
if (ConversationTextFullPosX > ConversationBoxFullSizeX * 0.90)
{
for (int i = TextLetterIteration - 1; i >= 0; i--)
{
if (TemporaryString.Mid(i, 1) == " ")
{
TemporaryString.InsertAt(i + 1, "\n");
break;
}
}
WordWrapString.Add(TemporaryString.Mid(0, TextLetterIteration));
TemporaryString = TemporaryString.Mid(TextLetterIteration, TemporaryString.Len());
TextLetterIteration = 0;
}
}
If you’re using this code you’ll want to clean it up and make it work for you. But it’s incredibly modular and flexible.