Last active
May 14, 2023 11:16
-
-
Save Aaron1178/d97fda37d6baffa660efd0bd0ca6399b to your computer and use it in GitHub Desktop.
Use the Asset Registry to Register WidgetBlueprints as Primary Asset Types of their respective base class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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