AHUD::GetTextSize() does return width and height of 0

Hi, I am trying the following C++ code:

float width = 0.0f, height = 0.0f;
 HUD->GetTextSize("String", width, height);

However, both width and heightt variables are always 0. So I tried the following instead:

float width = 0.0f, height = 0.0f;
HUD->GetTextSize("String", width, height, GEngine->GetMediumFont());

But without luck, both width and height are still 0. Any ideas?

Hey -

Looking at the code posted I would expect height and width to both be 0. Unless the value of the variables are being edited elsewhere then the 0.0f that you set when creating the variable is what the GetTextSize() function is using.

Cheers

, please have a look at the documentation here. It clearly states that this function returns the width and height of the given string via the second and third parameters.

So no, your answer is not correct. Why is it marked as correct answer here?

Hey -

Depending on where the call to GetTextSize() is being made, the canvas may or may not be valid. Overriding the DrawHUD() function of your hud class and calling GetTextSize within the DrawHUD() loop should update the variables properly.

Cheers

Hmm… I am using a normal UMG widget as HUD, which is using Blueprint. Can I still use the approach you suggested, that is, to override the DrawHUD() function in C++, even though the rest of the HUD is Blueprint, as said? Or is there another place where I could call that GetTextSize() method?

Hey -

I’m going to need further explanation or screenshots to help me understand what you’re referring to. What class is the code you posted originally in? What is the parent of that class? How does the code relate to your UMG widget? Please list the steps in your setup so I can try to match your setup.

Sure, my use case is quite straight-forward. I have created a library class in C++, like this:

UCLASS()
class GLOW_API UMyStaticToolkit : public UObject
{
    GENERATED_BODY()

public:
    static void SetActorDebugText(UWorld* World, AActor* Actor, FString String, FColor Color = FColor::White);
};

The implementation of this class looks like this:

void UMyStaticToolkit::SetActorDebugText(UWorld* World, AActor* Actor, FString String, FColor Color)
{
    AHUD* HUD = World->GetFirstPlayerController()->GetHUD();
    float width = 0.0f, height = 0.0f;
    if(GEngine != nullptr)
    {
        HUD->GetTextSize(String, width, height, GEngine->GetMediumFont());
        PrintString(FString::SanitizeFloat(width));  // this prints out "0"
    }

    HUD->RemoveDebugText(Actor);
    HUD->AddDebugText(String, Actor, -1.0f, FVector(0.0f, 0.0f, 100.0f), FVector(0.0f, 0.0f, 100.0f), Color, true, false, true);
}

Now I simply call this static method UMyStaticToolkit::SetActorDebugText() from other places in my C++ code in order to print some debug text above the head of my actor(s). This works, text is being rendered. However, the width returned by GetTextSize() is always 0 …

So in this case the issue is as I mentioned that the Canvas is not valid so the function that would set the width and height is not getting called. A simple solution would be to create a HUD class that overrides the DrawHUD() function and call GetTextSize there. Then in your SetActorDebugText() function you would create a pointer to that class and call the DrawHUD() function.

Thanks for your reply, . I am not sure whether I fully understand your suggested solution. When I create this custom class derived from AHUD, where should I instanciate and “put” it? I mean, do I need to set or activate that the somewhere, or is it sufficient to simply instanciate my custom class then somewhere and just call DrawHUD() withing anything else?

After further investigation, I have to apologize for my previous statement. It seems calling the DrawHUD function from elsewhere is not as simple as I had thought it to be. I’m still looking for other ways to use GetTextSize() outside of a HUD class.

Thanks, I am looking forward to any guidance you can give me!

Hey -

From what I’ve found in testing the GetTextSize() function it seems to only work successfully inside the AHUD::DrawHUD() function since this is when the canvas is valid and can update properly. It may be possible to call the function inside DrawHUD (which is updated every frame) and store the results from the call. This way rather than passing values to the function you can retrieve the values after the call has been made (likely with a Get() function inside your custom HUD class).

Ok, I see what you mean. Thanks for the idea, storing the value seems to be a reasonable approach. One more question though: When I derive from the AHUD class and override that DrawHUD() method, where do I need to “enable” or set my custom child class, so that UE4 picks it up?

Inside the editor you can click the Settings toolbar button and open the World Settings. In the Game Mode section you can set a custom game mode (class or blueprint). If you use a custom game mode blueprint then you can select your custom HUD class in the Selected GameMode drop down. If you are using a GameMode code class then you set which HUD class to use inside the game mode class.