
Specifying a UCLASS as the type of a UPROPERTY
So, you've constructed some custom UCLASS
intended for use inside UE4. But how do you instantiate them? Objects in UE4 are reference-counted and memory-managed, so you should not allocate them directly using the C++ keyword new
. Instead, you'll have to use a function called ConstructObject
to instantiate your UObject
derivative. ConstructObject
doesn't just take the C++ class of the object you are creating, it also requires a Blueprint class derivative of the C++ class (a UClass*
reference). A UClass*
reference is just a pointer to a Blueprint.
How do we instantiate an instance of a particular Blueprint from C++ code? C++ code does not, and should not, know concrete UCLASS
names, since these names are created and edited in the UE4 Editor, which you can only access after compilation. We need a way to somehow hand back the Blueprint class name to instantiate to the C++ code.
The way we do this is by having the UE4 programmer select the UClass
that the C++ code is to use from a simple drop-down menu listing all the Blueprints available (derived from a particular C++ class) inside the UE4 Editor. To do this, we simply have to provide a user-editable UPROPERTY
with a TSubclassOf<C++ClassName>
-typed variable. Alternatively, you can use FStringClassReference
to achieve the same objective.
This makes selecting the UCLASS
in the C++ code is exactly like selecting a texture to use. UCLASS
should be considered as resources to the C++ code, and their names should never be hardcoded into the code base.
Getting ready
In your UE4 code, you're often going to need to refer to different UCLASS
in the project. For example, say you need to know the UCLASS
of the player object so that you can use SpawnObject
in your code on it. Specifying a UCLASS
from C++ code is extremely awkward, because the C++ code is not supposed to know about the concrete instances of the derived UCLASS
that were created in the Blueprints editor at all. Just as we don't want to bake specific asset names into the C++ code, we don't want to hardcode derived Blueprints class names into the C++ code.
So, we use a C++ variable (for example, UClassOfPlayer
), and select that from a Blueprints dialog in the UE4 editor. You can do so using a TSubclassOf
member or an FStringClassReference
member, as shown in the following screenshot:

How to do it...
- Navigate to the C++ class that you'd like to add the
UCLASS
reference member to. For example, decking out a class derivative with theUCLASS
of the player is fairly easy. - From inside a
UCLASS
, use code of the following form to declare aUPROPERTY
that allows selection of aUClass
(Blueprint class) that derives fromUObject
in the hierarchy:UCLASS() class CHAPTER2_API UUserProfile : public UObject { UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Unit) TSubclassOf<UObject> UClassOfPlayer; // Displays any UClasses // deriving from UObject in a dropdown menu in Blueprints // Displays string names of UCLASSes that derive from // the GameMode C++ base class UPROPERTY( EditAnywhere, meta=(MetaClass="GameMode"), Category = Unit ) FStringClassReference UClassGameMode; };
- Blueprint the C++ class, and then open that Blueprint. Click on the drop-down menu beside your
UClassOfPlayer
menu. - Select the appropriate
UClassOfPlayer
member from the drop-down menu of the listedUClass
.
How it works…
TSubclassOf
The TSubclassOf< >
member will allow you to specify a UClass
name using a drop-down menu inside the UE4 editor when editing any Blueprints that have TSubclassOf< >
members.
FStringClassReference
The MetaClass
tag refers to the base C++ class from which you expect the UClassName
to derive. This limits the drop-down menu's contents to only the Blueprints derived from that C++ class. You can leave the MetaClass
tag out if you wish to display all the Blueprints in the project.