UMG covers subitles played by PlayDialogueAtLocation

So after a lot of searching and not a whole lot of finding answers. I’ve discovered that there is nothing you can do about this in Blueprints, sorry folks. There is however, a solution if you want to dive into cpp, and its actually a really easy change to move the location the text shows up on the screen. The file you want is SubtitleManager.cpp and is located in your engines source code directory Engine/Source/Runtime/Engine/Private/SubtitleManager.cpp

One you have this open in visual studios you want to find the DisplaySubtitle function. This function uses the canvas to draw a text item which renders directly to the players display, so it is not compatible in any way with UMG and widgets, which is why changing the TextItem.Depth won’t have any effect on the draw order. Instead, the best you can hope for is to be able to move the location to somewhere you don’t have any active UI elements. I’m guessing there could be a way to program this function to implement a UMG solution and expose the z order and location properties to a blueprint you could then edit, but I didn’t have time to do that. Instead I had the function draw the code from the top down instead of the bottom up due to our game having a hot bar at the bottom. Below is the newly modified code (only a few small changes).

//For displaying subtitles to a good location
void FSubtitleManager::DisplaySubtitle(FCanvas* Canvas, FActiveSubtitle* Subtitle, FIntRect& Parms, const FLinearColor& Color)
{
	if (OnSetSubtitleTextDelegate.IsBound())
	{
		// If we have subtitle displays, they should be rendered directly through those, not via the canvas.
		DisplaySubtitle_ToDisplays(Subtitle);
		return;
	}

	// These should be valid in here
	check(GEngine);
	check(Canvas);
	check(Subtitle != nullptr);

	CurrentSubtitleHeight = 0.0f;

	// This can be NULL when there's an asset mixup (especially with localization)
	if (!GEngine->GetSubtitleFont())
	{
		UE_LOG(LogSubtitle, Warning, TEXT("NULL GEngine->GetSubtitleFont() - subtitles not rendering!"));
		return;
	}

	float FontHeight = GEngine->GetSubtitleFont()->GetMaxCharHeight();
	float HeightTest = Canvas->GetRenderTarget()->GetSizeXY().Y;
	int32 SubtitleHeight = FMath::TruncToInt((FontHeight * MULTILINE_SPACING_SCALING));
	FIntRect BackgroundBoxOffset = DrawStringOutlineBoxOffset;
	//SYMMETRIC - Set the minimum to be 1/5 of the maximum - jb
	Parms.Min.Y += Parms.Max.Y/5;
	// Needed to add a drop shadow and doing all 4 sides was the only way to make them look correct.  If this shows up as a framerate hit we'll have to think of a different way of dealing with this.
	if (Subtitle->bSingleLine)
	{
		const FText& SubtitleText = Subtitle->Subtitles[Subtitle->Index].Text;

		if (!SubtitleText.IsEmpty())
		{
			
			// Display lines up from the bottom of the region
			//SYMMETRIC - Changed to display lines down from the top of the region -jb
			Parms.Min.Y += SUBTITLE_CHAR_HEIGHT;
			FCanvasTextItem TextItem(FVector2D(Parms.Min.X + (Parms.Width() / 2), Parms.Min.Y), SubtitleText , GEngine->GetSubtitleFont(), Color);
			{
				TextItem.Depth = SUBTITLE_SCREEN_DEPTH_FOR_3D;
				TextItem.bOutlined = true;
				TextItem.bCentreX = true;
				TextItem.OutlineColor = FLinearColor::Black;
			}
			Canvas->DrawItem(TextItem);		
			CurrentSubtitleHeight += SubtitleHeight;
		}
	}
	else
	{
		for (int32 Idx = Subtitle->Subtitles.Num() - 1; Idx >= 0; Idx--)
		{
			const FText& SubtitleText = Subtitle->Subtitles[Idx].Text;

			// Display lines up from the bottom of the region
			//SYMMETRIC - Changed to dispay lines down from the top of the region -jbogaard
			if (!SubtitleText.IsEmpty())
			{
				FCanvasTextItem TextItem(FVector2D(Parms.Min.X + (Parms.Width() / 2), Parms.Min.Y), SubtitleText, GEngine->GetSubtitleFont(), Color);
				{
					TextItem.Depth = SUBTITLE_SCREEN_DEPTH_FOR_3D;
					TextItem.bOutlined = true;
					TextItem.bCentreX = true;
					TextItem.OutlineColor = FLinearColor::Black;
				}
				Canvas->DrawItem(TextItem);
				Parms.Min.Y -= SubtitleHeight;
				CurrentSubtitleHeight += SubtitleHeight;

				// Don't overlap subsequent boxes...
				BackgroundBoxOffset.Max.Y = BackgroundBoxOffset.Min.Y;
			}
		}
	}
}
1 Like