Why use TSubclassOf<>

In 11:08 instructor used TSubclassOf<> camera shake. Why and when to use tSubclassOf ?

In this particular case, the ClientPlayCameraShake is expecting a TSubclassOf passed in as a parameter, so we’re pretty much enforced to do so this way.

In other instances where we used TSubclassOf, it was to be able to access not only the C++ class, but also the extra properties found on the Blueprint of said class. When you use TSubclassOf, you’re storing a UClass inside your variable, which has the ability to exchange information between the C++ and the Blueprint sides.

For example, on BasePawn.h, if we were to declare the Projectile class like this:

AProjectile* ProjectileClass;

we would only be able to access the C++ class stuff. We wouldn’t be able to spawn the static mesh that we linked to the Projectile on its Blueprint, or use any of the VFX stuff that we learn later (smoke trails and hit particles).

We should be declaring it like this for us to be able to access stuff from its Blueprint:

UPROPERTY(EditDefaultsOnly, Category = "Combat")
TSubclassOf<AProjectile> ProjectileClass;
1 Like

Because we essentially want to store a type in a variable. UClass represents the reflected metadata of a given class and as stated by @sziwipx that is what TSubclassOf<T> stores. When spawning an actor you need the UClass* of some type T not an T*.

A little misleading as you can get the UClass* via GetClass()

2 Likes

Ohhh I didn’t know this. So the TSubclassOf kinda acts like a shortcut for those two steps? Declaring ‘AProjectile* Projectile’ + using GetClass() on the .cpp and directly declaring it as TSubclassOf would be the same thing?

Thanks for the info! I knew something about my answer was slightly off haha.

1 Like

Many thanks for all great explanations. I can not select multi solutions :slight_smile:

No. GetClass() is what you would use for runtime purposes where you don’t know the exact type at compile time. For example say you wanted to create a volume that duplicates any actor that overlaps, you would call GetClass() on that overlapped actor. (Try make this)

StaticClass() which is a static member function on all UObjects is what gets the UClass* for the respective type. You could give the variable a default value of the AProjectile by doing

TSubclassOf<AProjectile> ProjectileClass = AProjectile::StaticClass();

But that’s not the blueprint derived class you made so any modifications you did there (set the mesh, the various properties like speed etc.) aren’t going to be present on the spawned actor if you just used AProjectile::StaticClass().

There’s just no way to refer to the derived blueprint class from C++ without the use of ConstructorHelpers which would need a string reference to the asset. It’s better to do it within the editor as done in the course.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms