How to declare a C++ variable of blueprint type? (UE4-4.23.1)

Hello, I have a widget blueprint that handles some UI stuff, lets call it MyWidgetUI. I was able to create a variable with the type of MyWidgetUI in another actor blueprint, lets call this UselessUIActor. Then I decided to turn my UselessUIActor into a subsystem because I realized there is no reason for UselessUIActor to exist in the game world, and the event graph is simple enough in logic that I can turn it into code.

So I created a blank C++ class and turned it into a subsystem. The problem is that I can’t figure out how to declare a variable of type MyWidgetUI in my new C++ subsystem. Searched online for a while, but I haven’t been able to find a definitive answer. Can someone tell me if this is possible in UE4? And if it is, how to properly do this?

The end goal is for me to be able to get the subsystem in an event graph, and pull a wire off of it to get a MyWidgetUI and pass it some data.

UCLASS()
class MYTEST_API UMySubsystemTest : public UGameInstanceSubsystem
{
	GENERATED_BODY()
public:
	UMySubsystemTest();
	
	MyWidgetUI m_WidgetUI; //<- How do I declare a variable of a blueprint type?
};

Any help would be appreciated, thanks in advance!

Unfortunately, so far as I know, you can’t do so directly; Blueprint classes don’t exist at the stage where you’re compiling C++ code, rather only after the editor compiles the Blueprint into a C++ variant when actually building the project (or running PIE, or whatever).

I suspect the closest you could come would be to define a base class in C++ with prototypes of the functions you wanted to be able to call (as BlueprintNative functions), call it UBaseWidgetUI or whatever. Then subclass that class with a Blueprint and implement the necessarily functionality.

Then you could have the variable in your subsystem be a UBaseWidget instead, and—since your MyWidgetUI Blueprint class subclassed UBaseWidgetUI—you could use an instance of the Blueprinted class as though it were a native UBaseWidgetUI.

1 Like

Thanks for the reply, this is the solution I was looking for. I came across some more information after this that I felt like needed to be included, and I can’t edit my original post for some reason.

I created a C++ base class that inherits from UUserWidget to serve as a parent for MyWidgetUI.
IMPORTANT NOTE: Right clicking on the C++ class in the content browser and creating a blueprint from the C++ class WILL NOT give access to the Designer tab even though the C++ class inherits from UUserWidget.
The correct way to do this is to manually create a Widget Blueprint by right clicking in the content browser and selecting “User Interface->Widget Blueprint”, opening it up and then selecting “File->Reparent Blueprint” to manually change the parent class to the C++ base class.
Also, it’s a good idea to not call the blueprint the same as the C++ class, as it will show up as identical text when you try to cast it in the graph view. I append the “BP_” prefix to the name of the blueprint to help distinguish between the blueprint, and the parent C++ class.

So in the end, I have a pointer in my subsystem to the base class which can store my blueprint that I create in the graph. So whenever I need to get access to the blueprint I can get it from the subsystem, and downcast it to the blueprint.

<.h file for widget parent class>
UCLASS()
class MYTEST_API UMyWidgetUI: public UUserWidget
{
	GENERATED_BODY()
public:
	UMyWidgetUI(const FObjectInitializer& ObjectInitializer);
	~UMyWidgetUI();
};

<.cpp file for widget parent class>
UMyWidgetUI::UMyWidgetUI(const FObjectInitializer& ObjectInitializer)
   : UUserWidget(ObjectInitializer)
{

}
UMyWidgetUI::~UMyWidgetUI()
{

}

<subsystem header file>
UCLASS()
class MYTEST_API UMySubsystemTest : public UGameInstanceSubsystem
{
	GENERATED_BODY()
public:
	UMySubsystemTest();
	
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	UMyWidgetUI* m_WidgetUI; //I called my blueprint BP_MyWidgetUI
};

Honestly, this is just good practice regardless of anything else.

(Glad the rest helped!)

1 Like

TSubclassOf<UUserWidget> WidgetClass = ConstructorHelpers::FClassFinder<UUserWidget>(TEXT("/ShooterCore/Weapons/Granade/W_GrenadeCooldown")).Class;