Download

Can't find Blueprint-Derived classes using asset registry in 4.17?

As the title says, I can’t seem to find certain classes with the asset manager in 4.17. I just want to find all assets of a given type with ease, and without having to define them in a list anywhere.

The class is really simple. I don’t think the ‘AssetRegistrySearchable’ tag works with UCLASS, but it doesn’t make a difference whether it’s there or not.



UCLASS(Config = "Game", Blueprintable, HideCategories = "Object", AssetRegistrySearchable)
class ECGAME_API UECGame_AbilityData : public UObject
{
	GENERATED_BODY()
public:
	UECGame_AbilityData(const FObjectInitializer& OI);

#if WITH_EDITOR
	virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
	void CheckDependencies();
#endif

	UPROPERTY(EditDefaultsOnly, Category = "Ability")
	EOrbType OrbType;
	UPROPERTY(EditDefaultsOnly, Category = "Ability")
	TAssetSubclassOf<UECGame_InventoryBase> AbilityBlueprint;
	UPROPERTY(EditDefaultsOnly, Category = "Requirements")
	int32 CreditCost;
	UPROPERTY(EditDefaultsOnly, Category = "Requirements")
	int32 RankRequirement;
	UPROPERTY(EditDefaultsOnly, Category = "Requirements")
	TArray<TSubclassOf<UECGame_AbilityData>> Prerequisites;
	UPROPERTY(EditDefaultsOnly, Category = "User Interface")
	FText DisplayName;
	UPROPERTY(EditDefaultsOnly, Category = "User Interface")
	FText Description;
	UPROPERTY(EditDefaultsOnly, Category = "User Interface")
	UTexture2D* UIIcon;

	// Whether the ability is enabled in the game or not.
	UPROPERTY(EditDefaultsOnly, Config, Category = "Ability")
	uint8 bEnabled : 1;
};


I’ve created some Blueprint’s of this class in the content browser, but I can’t find them no matter what. The API has changed in 4.17, with no documentation… This code fails on the first assert because no assets are found. Any ideas?



void UECGame_GameInstance::PopulateGameAbilities()
{
	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
	TArray<FAssetData> AssetData;

	const FName ClassName = UECGame_AbilityData::StaticClass()->GetFName();
	AssetRegistryModule.Get().GetAssetsByClass(ClassName, AssetData, true);
	ASSERTV(AssetData.Num() > 0, TEXT("No Abilities Found"));

	for (const FAssetData& AssetItr : AssetData)
	{
		UECGame_AbilityData* Data = Cast<UECGame_AbilityData>(AssetItr.GetAsset());
		ASSERTV(Data != nullptr, TEXT("Invalid Ability Data"));

		if (Data->bEnabled)
		{
			GameAbilities.AddUnique(Data);
		}
	}

	UE_LOG(LogECGame, Log, TEXT("Ability Search Complete. Num Abilities: %i"), GameAbilities.Num());
}


This code that uses the asset registry worked fine when I was using Data Tables. Now all of a sudden it can’t find my Objects?

I’ve even tried searching ALL blueprint classes… then I get nothing :confused:



	FARFilter SearchFilter;
	SearchFilter.ClassNames.Add(UBlueprint::StaticClass()->GetFName());
	SearchFilter.ClassNames.Add(UBlueprintGeneratedClass::StaticClass()->GetFName());
	SearchFilter.ClassNames.Add(UECGame_AbilityData::StaticClass()->GetFName());
	//SearchFilter.ClassNames.Add(TEXT("ECGame_AbilityData_C"));
	AssetRegistryModule.Get().GetAssets(SearchFilter, AssetData);
	ASSERTV(AssetData.Num() > 0, TEXT("No Assets Found"));

	for (const FAssetData& AssetItr : AssetData)
	{
		ASSERTV(AssetItr.GetAsset() != nullptr, TEXT("Invalid Asset Found!"));

		UECGame_AbilityData* Data = Cast<UECGame_AbilityData>(AssetItr.GetAsset());
		if (Data)
		{
			GameAbilities.AddUnique(Data);
		}
	}


Bump - still can’t find anything!

Blueprint assets are of type UBlueprint::StaticClass(). They’re not objects of the class they represent, so you can’t search for that class directly through the asset registry in the normal way. Using IAssetRegistry::GetDerivedClassNames is one option, though you have to deal with names and then load the classes by name manually. I wrote this article a while back that should be mostly still applicable.

It’s basically way more effort than it should be. Not sure if there’s anything in the new asset management system that helps with this.

I did something similar. Collecting all blueprints and even their Functions, so i could have a fully customizable/moddable platform.

Maybe


SearchFilter.bRecursiveClasses = true;

will help you.
But you have to remove


SearchFilter.ClassNames.Add(UBlueprint::StaticClass()->GetFName()); SearchFilter.ClassNames.Add(UBlueprintGeneratedClass::StaticClass()->GetFName()); 

then. PS: for the forum maintainers: the new editor sucks big time when you copy/paste code. (running firefox 55.0.3)

Another way of course would be to give your base class a TagAndValue, then you can search for them more comfortably.

SearchFilter.bRecursiveClasses = true; Ugh… that was probably what I was missing! I actually solved this by creating the UObjects directly as assets rather than blueprint derived classes (using asset factory), so got around it that way.