Searching for BP-class by property default value: Why does it succeed ONLY if the uasset of this type is already placed on level?

I’m trying to search the blueprint class by its property (named “TypeId”) default value. I need it to be able to spawn a pawn on given type id.

To search this BP-class I use this method:

TSubclassOf<AMyPawn> AMyPawn::GetClassByTypeID(const int32 TypeID)
{
	if (TypeID <= 0)
		return nullptr;

	FARFilter Filter;
	Filter.bRecursiveClasses = true;
	//Filter.bRecursivePaths = true;
	Filter.ClassNames.Add(UBlueprint::StaticClass()->GetFName());
	Filter.ClassNames.Add(UBlueprintGeneratedClass::StaticClass()->GetFName());
	Filter.TagsAndValues.Add(FName("TypeId"), FString::FromInt(TypeID));

	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(FName("AssetRegistry"));
	IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();

	//TArray<FString> PathsToScan;
	//PathsToScan.Add(TEXT("/MyGame/Content/MyPawns/"));
	//AssetRegistry.ScanPathsSynchronous(PathsToScan);

	TArray<FAssetData> AssetsData;
	if (!AssetRegistry.GetAssets(Filter, AssetsData))
	{
		return nullptr;
	}

	for (const FAssetData& AssetData : AssetsData)
	{
		UPackage* Package = FindPackage(nullptr, *AssetData.PackageName.ToString()); //<<<<< Here I get Package == NULL
		const FString* GeneratedClassName = AssetData.TagsAndValues.Find(TEXT("GeneratedClass"));
		if (Package && GeneratedClassName)
		{
			UClass* ResultClass = LoadClass<AMyPawn>(Package, *(*GeneratedClassName), NULL, LOAD_None, NULL);
			if (ResultClass)
			{
				return ResultClass;
			}
		}
	}
  
	return nullptr;
}

In line, marked by “//<<<<< Here …” comment, I get Package == NULL. And so the function result is nullptr.

But, if I place the uasset of type, I search for, on level manually in editor, then at runtime all works good and the class is found.

It seems like when I place an uasset on level, some info about its BP-class is stored to something like “catalog”, which is used to run-time searches for classes.
And if I there are no uassets of current class on level, the search fails.

BUT! In both cases AssetsData, fulfilled by AssetRegistry.GetAssets(Filter, AssetsData) (see a couple lines above) is fulfilled properly - it always contains the only entry with correct data of the class, I search for (its path, name & e.t.c.).

Please help me to figure out, why does it work so? And how can I avoid the necessity of placing uassets on level to succeed in search for them?

Thanks a lot!

When you use FindPackage - yes, asset must be placed on level, because FindPackage only searched already loaded packages.
Howewer, if asset not used yet, you need call LoadPackage, to load package from disk.