How to get a UClass* to a Blueprint without loading it?


I have a C++ class called ‘AEntity’, which is the base for multiple Blueprint classes created in the editor. The goal is to get a list of Blueprint classes deriving from ‘AEntity’, so that a random entry can be selected later for actual spawning.

Discovering the assets seems to be working, I can get the ‘FAssetData’ of all derived Blueprints, but I am confused about how to get the actual ‘UClass*’ so I can return

TArray<TSublassOf<AEntity>> EntityBlueprintClasses;

‘FAssetData’ provides us with a ‘GetClass()’ function, but that returns a class called ‘Blueprint’, which might be related to ‘FoundAssetData.IsUAsset()’ returning true.

Now the solutions that I have encountered suggested using ‘FoundAssetData.GetAsset()’ and casting it to ‘UBlueprint’ so I can get the ‘GeneratedClass’, but that would load the object if it doesn’t exist, which I don’t want for two reasons:
-there could be hundreds of assets that I would not want to load just to get their classes (if such a thing is possible)
-the function that collects the assets can be called from other threads, and loading ‘UObjects’ is only allowed in the game thread.

Any help would be appreciated.

No, there’s no way to access the UClass information for a blueprint without loading the blueprint. Fundamentally the Blueprint is the UClass.

The option that I’ve usually encountered for this is a second data structure. One job called them Infos, another Templates (no relation to the C++ feature) and my hobby projects use Definition. No matter what you call them their purpose is to store shared, always loaded, information or meta-data about the class. It would also include a reference to the blueprint so that if it’s selected, you know the type of object to spawn. This is sort of like the Flyweight Pattern if you’re at all familiar with the Gang of Four Design Patterns book.

Maybe an example would help. Let’s say you’ve got a Weapon actor, AWeapon. But you want to display all you weapons in your shop without loading all that content (as you rightly point out). So instead we also make a UWeaponInfo. This asset would be loaded all the time and have all the information you need to populate your UI, maybe a Display Name, an Icon, a description, etc. Usually the ones I’ve dealt with would also have most of the gameplay data as well like damage information. This might sound weird, why wouldn’t you configure that on each AWeapon? Well you probably want to include that information in your UI’s so it needs to be in a place that is loaded when the blueprint class isn’t. It has the additional upside of storing shared data for multiple instances (say NPC’s) in one place instead of duplicating static information in every instance of the NPC. Whether of not this is a compelling argument depends on the size of your Infos and the number of objects you’re creating.

If this sounds like something UE4 does, it sort of does. There’s support for something called Sparse Class Data that allows multiple instances of the same object type to share some data (stuff that’s not changing during runtime). I haven’t used the feature though so I’m not sure if there is a way to access the Sparse Class Data for a class without loading it.