Canvas Word Wrapper - Update!

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. :slight_smile: