Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Use the Asset Registry to Register WidgetBlueprints as Primary Asset Types of their respective base class.
void UMyAssetManager::StartInitialLoading()
{
Super::StartInitialLoading();
UE_LOG(LogMyAssetManager, Log, TEXT("Initializing MyAssetManager"))
if ( !bHasScannedForWidgetBlueprints )
{
/** Scan for and Register Widget Blueprints with the Asset Manager*/
Get().RegisterWidgetBlueprintsPrimaryAssets<UMyBaseUUserWidgetClass>();
}
}
/** Note: Class names etc have been changed for public use. */
template <class T> void UMyAssetManager::RegisterWidgetBlueprintsPrimaryAssets( const FString Path /*= "/Game"*/, const bool bShowAssetManagerDump /*= false*/ )
{
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(FName("AssetRegistry"));
IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();
if ( Path.IsEmpty() )
{
UE_LOG(LogMyAssetManager, Warning, TEXT("Path parameter is empty. Please specify a content directory"));
return;
}
TArray<FString> ContentPaths;
ContentPaths.Add(Path);
/** Scan ContenPaths recursivley */
AssetRegistry.ScanPathsSynchronous(ContentPaths, true);
TSet<FName> DerivedNames;
{
TArray<FName> BaseNames; //The base Class Names
BaseNames.Add(T::StaticClass()->GetFName());
TSet<FName> Excluded;
/** Get a list of class names derived from BaseNames */
AssetRegistry.GetDerivedClassNames(BaseNames, Excluded, DerivedNames);
}
/** Create a FARFilter to search for WidgetBlueprint type classes */
FARFilter Filter;
Filter.ClassNames.Add(FName("WidgetBlueprint"));
Filter.bRecursivePaths = true;
Filter.bRecursiveClasses = true;
TArray<FAssetData> AssetList;
/** Get a list of FAssetData the matches the search criteria of the FARFilter */
AssetRegistry.GetAssets(Filter, AssetList);
for ( FAssetData Asset : AssetList )
{
/** Get the the class this blueprint generates (this is stored as a full path e.g "WidgetBlueprintGeneratedClass'/Game/Assets/NewWidgetBlueprint.NewWidgetBlueprint_C'") */
FAssetTagValueRef GeneratedClassPathPtr = Asset.TagsAndValues.FindTag(TEXT("GeneratedClass"));
if ( GeneratedClassPathPtr.IsSet() )
{
/** Convert path to just the name part e.g "/Game/Assets/NewWidgetBlueprint.NewWidgetBlueprint_C" */
const FString ClassObjectPath = FPackageName::ExportTextPathToObjectPath(GeneratedClassPathPtr.AsString());
const FString ClassName = FPackageName::ObjectPathToObjectName(ClassObjectPath);
/** Check if this class is in the derived set */
if ( !DerivedNames.Contains(*ClassName) )
{
continue;
}
/** The SoftObjectPath to our class */
FSoftObjectPath SoftPath(ClassObjectPath);
/** Try to cast the UObject returned from SoftPath.TryLoad() to UWidgetBlueprintGeneratedClass */
if ( UWidgetBlueprintGeneratedClass* Cls = Cast<UWidgetBlueprintGeneratedClass>(SoftPath.TryLoad()) )
{
/** Cast the UWidgetBlueprintGeneratedClass' default object to UMyBaseUUserWidget */
if ( T* UIAsset = Cast<T>(Cls->GetDefaultObject()) )
{
/** Register the specific WidgetBlueprint Asset as a PrimaryAsset using the UMyBaseUUserWidget->GetPrimaryAssetId() function.
* This is neccessary as Asset->GetPrimaryAssetId() will not return the proper PrimaryAssetId as it will auto generate to
* "MyBaseUUserWidget:AssetName".
*/
Get().RegisterSpecificPrimaryAsset(UIAsset->GetPrimaryAssetId(), Asset);
}
}
}
}
/** Optional debug information*/
if ( bShowAssetManagerDump )
{
UE_LOG(LogMyAssetManager, Log, TEXT("Dumping Asset Manager Info"));
Get().DumpAssetRegistryInfo();
Get().DumpAssetTypeSummary();
Get().DumpLoadedAssetState();
}
bHasScannedForWidgetBlueprints = true;
}
template <class T> T* UMyAssetManager::GetWidgetFromAssetData( const FAssetData AssetData, UGameInstance* GameInstance) const
{
FAssetTagValueRef GenClassTag = AssetData.TagsAndValues.FindTag(FName("GeneratedClass"));
/** Check and see if the "GeneratedClass" tag was found */
if ( GenClassTag.IsSet() )
{
const FString ObjPath = FPackageName::ExportTextPathToObjectPath(GenClassTag.AsString());
const FSoftObjectPath SoftObjectPath(GenClassTag.AsString());
/** Try and load the class and cast it to UWidgetBlueprintGeneratedClass */
if ( UWidgetBlueprintGeneratedClass* BpClass = Cast<UWidgetBlueprintGeneratedClass>(SoftObjectPath.TryLoad()) )
{
/** Try to CreateWidget of type T with a valid UGameInstance and the UWidgetBlueprintGenerated class above */
if( T* Object = CreateWidget<T>(GameInstance, BpClass) )
{
/** If our Object widget is valid, we return it */
return Object;
}
}
}
return nullptr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment