Download

C++ GameMode with Blueprint HUD?????????

This is really really really annoying me.

I have a HUD, made out of a Widget Blueprint.

bpc.PNG

And my GameMode is a C++ class.

Header…


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/GameMode.h"
#include "Trek_OnGameMode.generated.h"

class AEnemy;

UCLASS()
class TREK_ON_API ATrek_OnGameMode : public AGameMode
{
	GENERATED_BODY()
	
public:

	// Constructor
	ATrek_OnGameMode();

	// Array of current enemies
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enemies")
		TArray<AEnemy *> Enemies;
};

Implementation…


// Fill out your copyright notice in the Description page of Project Settings.

#include "Trek_On.h"
#include "Enterprise.h"
#include "Trek_OnGameMode.h"
#include "GameFramework/HUD.h"

ATrek_OnGameMode::ATrek_OnGameMode()
{
	static ConstructorHelpers::FObjectFinder<UClass> HUDFinder(TEXT("WidgetBlueprint'/Game/UI/GameHUD.GameHUD_C'"));

	DefaultPawnClass = AEnterprise::StaticClass();

	HUDClass = (UClass *) HUDFinder.Object;
}

This isn’t exactly rocket science here, I want the C++ GameMode to accept and use my BP HUD. The current code compiles, but no HUD appears.

I need this for a school project, help would be deeply appreciated.

-Cody

You can set it up in code, but its far easier and better IMO to set the classes in Editor.
Under Project Settings > Maps and Modes

This way you don`t have to hard code any classes.

^ It needs to be a HUD class to set it in Project Settings though / through the gamemode. I suggest creating a custom HUD, and having a bunch of TSubclassOf variables of UUserWidget, and adding them to the players’ screen during gameplay. This is how I do mine, and I can manage / access all widgets through the HUD relatively easily.

Wait so I should have subclassed HUD with my Blueprint instead of a BP Widget?

I can tell you the way I did it which I think is what TheJamsh is talking about. It is based on this tutorial but I did a lot more research before I understood what was going on, so apologies if this code looks familiar and I haven’t credited you as it was a while ago now and I can’t remember exactly where I went!

https://wiki.unrealengine.com/Extend_UserWidget_for_UMG_Widgets

First, the BP HUD you’ve made needs to be a UserWidget using the method above. Basically, create a UserWidget class in C++ and then set the parent class of the BP to that class.

Then we need to reference it in C++ and to load it to screen. In the header file you would have these, where the UserWidget class in this case is “UBuildMenuWidget”; simply change these to GameHUD or whatever you call your UserWidget: -


	// Reference UMG Asset in the Editor
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Widgets")
		TSubclassOf<class UUserWidget> WBuildMenu;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Widgets")
		UBuildMenuWidget* UBuildMenu;


Then to initialise it: -


	if (WBuildMenu) // Check if the Asset is assigned in the blueprint.
	{
		// Create the widget and store it.
		UBuildMenu = CreateWidget<UBuildMenuWidget>(this, WBuildMenu);
		// Extra check to  make sure the pointer holds the widget.
		if (UBuildMenu)
		{
			// Add it to the view port
			UBuildMenu->AddToViewport();
		}
	}


I did this in my PlayerController class, so you may need to reference it instead of “this” in the creation so it appears on the correct player screen; I am afraid I don’t know the details…

The final thing to do is to reference the widget within the owning class BP. In my case, I made a PlayerController class BP but it would be a GameMode one for you.
Within that BP, select the “Class Defaults” button on the top menu and you should see your widget reference on the right under the relevant category (“Widgets” in my case). Click the drop down and select your GameHUD BP (see attached screenshot).
a8641f4e9332d035e31760b4a62cb735a6c208b3.jpeg
If you haven’t already, you would need to select your GameMode as the Default GameMode under Project Settings->Maps & Modes.

As TheJamsh mentioned, I have a few of these widgets that I can swap between and even use as building blocks for other widgets.

Now, I don’t know if this is the correct way of doing this or even the best way, so I would like to hear feedback for my benefit as well as yours.

You don’t need any C++, and it’s actually super simple:

Just create a Blueprint that extends from HUD, and configure your gamemode to use this Blueprint as the HUD.

Then in the Begin Play event of this HUD Blueprint, create the UserWidget (“Create Widget”) you want to use for your HUD and add it to the Viewport (“Add to Viewport”).

If you have multiple HUDs for different gamemodes, you can of course create a variable for your UserWidget class in your HUD BP and then modify it in subclasses.

Note that “HUD” is completely unrelated to UserWidgets, but it’s always created anyway so it works well as a point of creation for your UserWidget HUD. You can also use it for canvas drawing functions if ever needed, which is useful e.g. to draw pixel perfect lines or full screen effects.

I did this by using a custom AHUD class and a widget blueprint. The custom AHUD class is specified in my custom GameMode as


HUDClass = AMasterRobotHUD::StaticClass();

The widget blueprint is created using the blueprint editor, so I can use the Unreal interface editor to create buttons etc.

To link it together, in my AMasterRobotHUD class, .h file:


class UClass * hudWidgetClass;
    class UUserWidget * hudWidget;
    virtual void BeginPlay () override;

Then in the constructor:


static ConstructorHelpers::FClassFinder<UUserWidget> hudWidgetObj (TEXT ("/Game/umg/GamePlayHUD_blueprint"));
    if (hudWidgetObj.Succeeded ()) {
        hudWidgetClass = hudWidgetObj.Class;
    } else {
        // hudWidgetObj not found
        hudWidgetClass = nullptr;
    }

You copy the bath to your blue print in the Unreal editor, by right-clicking and “Copy Reference”. Don’t forget to delete the beginning and the end of the reference string to get something similar to what I have above.
Also, add a function into your custom HUD class for when the game starts:


void AMasterRobotHUD::BeginPlay () {
    Super::BeginPlay ();
    if (hudWidgetClass) {
        // the player controller should be constructed by now so we can get a reference to it
        hudWidget = CreateWidget<UUserWidget> (this->GetOwningPlayerController (), this->hudWidgetClass);
        hudWidget->AddToViewport ();
    }
}

I copied the solution from elsewhere, I can’t remember where though anymore! Anyway, also remember that the HUD will ONLY show when you Launch, i.e., it doesn’t show when you Play via the Unreal editor.

Not sure why you need to do it this way, as this works:



static ConstructorHelpers::FClassFinder<ABorrowersHUD> HUDObjectFinder(TEXT("Blueprint'/Game/FirstPersonCPP/UI/GameHUD'"));
HUDClass = HUDObjectFinder.Class;


Since this topic has been reignited - it’s worth pointing out that referencing assets from code like this is a really bad habit.

The preferred workflow in UE4 is to create Blueprint subclasses and setup your defaults and references there. Referencing static classes from code is fine, but hardcoding asset references (and/or making a habit of it) can result in lots of issues like increased memory use, poor load times, difficulty renaming/moving assets etc.

Remember that the overhead of Blueprints comes only from the graph - setting properties and defaults has no overhead whatsoever, so you should always prefer to use it where possible.