Asset Manager with Packaged Primary Asset Types of UUserWidget


I have been doing some experimentation with the Asset Manager, and have come to an abrupt halt. I will try to explain as clearly and concise as I can.

I have a C++ class derived from UUserWidget which I want to be a new PrimaryAssetType, as this new class will be the base class for all user widgets in my project. I have overridden the GetPrimaryAssetId() function and have set up the Asset Manager in Project Settings.

My problem is that running in PIE and Standalone, I get the desired functionality I need. When I dump the Asset Manager using AssetManager.DumpAssetTypeSummary(); I see that it has 1 asset of PrimaryAssetType ‘UserInterface’. However, if I cook and package my project, AssetManager.DumpAssetTypeSummary(); states that there are 0 of PrimaryAssetType ‘UserInterface’.

I have also created a class from UPrimaryDataAsset and have a property of TSoftClassPtr and selected my UUserWidget derived class. I can set this to be any widgets created from my derived class. This solution works for PIE/Standalone and Cooked&Packaged games.

What I want to know, why is it not working with Blueprint Widgets? In the documentation it states that it can work with any UObject that overrides the GetPrimaryAssetId() function.

I have triple checked and tried many different combinations of Project Settings combinations. I have even selected a test widget from my UUserWidget base class as ‘Include Specific Asset’.

Also, in the Audit Asset window, it’s showing the correct PrimaryAssetType.

For some reason, I don’t think these widgets are being packaged properly.

That can happen, depending on your folder structure. By default, UE packages only those assets that are referenced in the levels or somewhere down the reference chain that starts from any of the levels.

There is a section in the project settings where you can specify content directories that should always be packaged, regardless of whether they’re referenced by something or not. Add your UI directory to that list and try again.

EDIT: Finished my reply before I saw your edit. Still worth a try.

Unfortunately that won’t work as I have correctly setup my Asset Manager. It’s in regards to the WidgetBlueprintGeneratedClass assets not being packaged.

I’ve even tried deriving from UWidgetBlueprintGeneratedClass but that throws errors on cooking.

During some R&D with the Asset Manager, I found that the Asset Manager could not find PrimaryAssets of a UUserWidget derived class in packaged builds.

When you create a widget and parent it to your UUserWidget derived class, unreal engine creates Widget Blueprints, which are of type UWidgetBlueprint, which is contained in the UMGEditor module. As such, you cannot use the UWidgetBlueprint class in your runtime packaged builds as it’s an editor only module.

What I didn’t know is that when you packaged Blueprints and Widget Blueprints, the packaging tool strips away the Blueprint and Widget Blueprint classes and you are left with the Generated classes: UBlueprintGeneratedClass & UWidgetBlueprintGeneratedClass, which is the reason the Asset Manager cannot find them as they are not the base class the Asset Manager is looking for in regards to the PrimaryAssetType.

This is where the Asset Registry comes in. Originally, thanks to the documentation (Asset Registry Documentation) quoting

The Asset Registry is an editor subsystem which gathers information about unloaded assets asynchronously as the editor loads.

I thought that it was an Editor Only module and could not be used at runtime. This is not the case and I put it down to bad documentation.

The Asset Registry showed me that my Widget Assets were indeed being packaged… which was a good sign. To register these Primary Widget Assets with the Asset Manager I created this function (With the help of a million posts on the internet & Discord). I wrapped it into a template so I could easily register widget blueprints with different Primary Asset base classes if needed.

I have also included a templated function to get the widget of UUserWidget derived class.

This fix works in packaged builds.