[Tutorial] Base HUD class

While working on the UI of Switch I noticed that HUD blueprints can become a bit messy. The way we do it in Switch is a HUD for the game that holds “main widgets” (scoreboard, ingame menu, game hud etc). Creating, managing and switching those widgets are the cause of the messy blueprint.

So that’s why I created a simple C++ base class for HUDs. The class has a map that holds a name for the main widget and a reference to the widget.

Header
All the functions are blueprintcallable so we can use them from the derived blueprint.


#pragma once
 
#include "GameFramework/HUD.h"
#include "SBaseHUD.generated.h"
 
class UUserWidget;
 
UCLASS()
class SHOOTER_API ASBaseHUD : public AHUD
{
    GENERATED_BODY()
    
public:
    ASBaseHUD();
 
    /** Adds a widget to the map */
    UFUNCTION(BlueprintCallable, Category = "MainWidget")
    void AddMainWidget(const FString& Name, UUserWidget* Widget);
 
    /** Creates the widget of the WidgetClass ands adds it to the map */
    UFUNCTION(BlueprintCallable, Category = "MainWidget")
    void CreateAddMainWidget(const FString& Name, UClass* WidgetClass, APlayerController* PlayerController);
 
    /** Removes the current widget from the screen and set the new one */
    UFUNCTION(BlueprintCallable, Category = "MainWidget")
    bool SetCurrentMainWidget(const FString& Name);
 
    /** Get a widget reference using a name */
    UFUNCTION(BlueprintCallable, Category = "MainWidget")
    UUserWidget* GetCurrentMainWidget(const FString& Name) const;
 
private:
    /** The map with references to all widgets */
    TMap<FString, UUserWidget*> MainWidgets;
 
    /** The current widget */
    UUserWidget* CurrentMainWidget;
};

Source


#include "Shooter.h"
#include "SBaseHUD.h"
#include "Blueprint/UserWidget.h"
 
ASBaseHUD::ASBaseHUD()
{
    CurrentMainWidget = nullptr;
}
 
 
void ASBaseHUD::AddMainWidget(const FString& Name, UUserWidget* Widget)
{
    if (!MainWidgets.Find(Name))
    {
        MainWidgets.Add(Name, Widget);
    }
}
 
 
void ASBaseHUD::CreateAddMainWidget(const FString& Name, UClass* WidgetClass, APlayerController* PlayerController)
{
    UUserWidget* Widget = CreateWidget<UUserWidget>(PlayerController, WidgetClass);
    if (!Widget)
    {
        return;
    }
 
    AddMainWidget(Name, Widget);
}
 
 
bool ASBaseHUD::SetCurrentMainWidget(const FString& Name)
{
    UUserWidget* Widget = *MainWidgets.Find(Name);
    if (Widget)
    {
        if (CurrentMainWidget)
        {
            CurrentMainWidget->RemoveFromParent();
        }
         
        Widget->AddToViewport();
        CurrentMainWidget = Widget;
    }
    return true;
}
 
 
UUserWidget* ASBaseHUD::GetCurrentMainWidget(const FString& Name) const
{
    return CurrentMainWidget;
}

Blueprint
Below you can see an example of creating and adding two different types of UserWidgets in the derived blueprint. After that one is set as current using the name.

Tip: Don’t “hardcode” the names like I did. Store them somewhere.

I hope someone can use this. Let me know if you have questions, feedback or if something is not working!

Originally posted on my blog