Asset not found when packaging game.

I have this code:
TArray SMainMenuWidget::GetMaps()
{
TArray MapNames;

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

FARFilter Filter;
Filter.ClassPaths.Add(UWorld::StaticClass()->GetClassPathName());
Filter.PackagePaths.Add("/Game/Maps");
Filter.bRecursivePaths = true;

TArray<FAssetData> AssetList;
AssetRegistry.GetAssets(Filter, AssetList);

for (const FAssetData& Asset : AssetList)
{
    FString MapName = Asset.AssetName.ToString();
    if (MapName != "LVL_MainMenu")
    {
        MapNames.Add(MapName);
    }
}

return MapNames;

}
Which works fine for finding maps, I am trying to do something similar for finding assets to cars, which more specifically would be skeletal mesh, physics asset and a animation blueprint.

I am trying to do it like this:

bool ATestVehiclePawn::FindCarAssets(FString& VehicleMeshPath, FString& PhysicsAssetPath, FString& AnimBPClassPath)
{
// Get base path for Car/4Wheeled directory
FString BaseCarPath = FPaths::ProjectContentDir() / TEXT(“Vehicles/Car/4Wheeled/”);

TArray<FString> Directories;
IFileManager& FileManager = IFileManager::Get();
FileManager.FindFiles(Directories, *(BaseCarPath / TEXT("*")), false, true);

UE_LOG(LogTemp, Warning, TEXT("BaseCarPath: %s"), *BaseCarPath);
UE_LOG(LogTemp, Warning, TEXT("Found directories: %d"), Directories.Num());

if (Directories.Num() == 0)
{
    UE_LOG(LogTemp, Error, TEXT("No car directories found in %s"), *BaseCarPath);
    return false;
}

// Select a random directory
int32 RandomIndex = FMath::RandHelper(Directories.Num());
FString SelectedDirectory = BaseCarPath / Directories[RandomIndex];
FString SelectedDirectoryContentPath = FString(TEXT("/Game/Carla/Static/Car/4Wheeled/")) + Directories[RandomIndex];

UE_LOG(LogTemp, Warning, TEXT("Selected directory: %s"), *SelectedDirectoryContentPath);

// Asset registry module
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FAssetData> AssetDataArray;

FAssetData SkeletalMeshAssetData;
FAssetData PhysicsAssetData;
FAssetData AnimBlueprintAssetData;

// Filter to search for assets in the selected directory
FARFilter Filter;
Filter.PackagePaths.Add(*SelectedDirectoryContentPath);
Filter.bRecursivePaths = true;
Filter.ClassPaths.Add(USkeletalMesh::StaticClass()->GetClassPathName());
Filter.ClassPaths.Add(UPhysicsAsset::StaticClass()->GetClassPathName());
Filter.ClassPaths.Add(UAnimBlueprint::StaticClass()->GetClassPathName());

AssetRegistryModule.Get().GetAssets(Filter, AssetDataArray);

UE_LOG(LogTemp, Warning, TEXT("Found assets: %d"), AssetDataArray.Num());

// Log all found assets for additional debugging
for (const FAssetData& AssetData : AssetDataArray)
{
    UE_LOG(LogTemp, Warning, TEXT("Asset: %s, Class: %s"), *AssetData.GetSoftObjectPath().ToString(), *AssetData.AssetClassPath.ToString());
}

// Assign the assets to the corresponding variables
for (const FAssetData& AssetData : AssetDataArray)
{
    if (AssetData.AssetClassPath == USkeletalMesh::StaticClass()->GetClassPathName())
    {
        SkeletalMeshAssetData = AssetData;
    }
    else if (AssetData.AssetClassPath == UPhysicsAsset::StaticClass()->GetClassPathName())
    {
        PhysicsAssetData = AssetData;
    }
    else if (AssetData.AssetClassPath == UAnimBlueprint::StaticClass()->GetClassPathName())
    {
        AnimBlueprintAssetData = AssetData;
    }
}

// Check we have found the necessary assets
if (!SkeletalMeshAssetData.IsValid() || !PhysicsAssetData.IsValid() || !AnimBlueprintAssetData.IsValid())
{
    if (!SkeletalMeshAssetData.IsValid())
    {
        UE_LOG(LogTemp, Log, TEXT("SkeletalMeshAssetData failed valid check"));
    }
    if (!PhysicsAssetData.IsValid())
    {
        UE_LOG(LogTemp, Log, TEXT("PhysicsAssetData failed valid check"));
    }
    if (!AnimBlueprintAssetData.IsValid())
    {
        UE_LOG(LogTemp, Log, TEXT("AnimBlueprintAssetData failed valid check"));
    }
    return false;
}

// Log the asset paths before assigning
UE_LOG(LogTemp, Warning, TEXT("SkeletalMeshAssetData path: %s"), *SkeletalMeshAssetData.GetSoftObjectPath().ToString());
UE_LOG(LogTemp, Warning, TEXT("PhysicsAssetData path: %s"), *PhysicsAssetData.GetSoftObjectPath().ToString());
UE_LOG(LogTemp, Warning, TEXT("AnimBlueprintAssetData path: %s"), *AnimBlueprintAssetData.GetSoftObjectPath().ToString());

// Assign paths
VehicleMeshPath = SkeletalMeshAssetData.GetSoftObjectPath().ToString();
PhysicsAssetPath = PhysicsAssetData.GetSoftObjectPath().ToString();
AnimBPClassPath = AnimBlueprintAssetData.GetSoftObjectPath().ToString();
AnimBPClassPath.Append(TEXT("_C"));

UE_LOG(LogTemp, Warning, TEXT("VehicleMeshPath: %s"), *VehicleMeshPath);
UE_LOG(LogTemp, Warning, TEXT("PhysicsAssetPath: %s"), *PhysicsAssetPath);
UE_LOG(LogTemp, Warning, TEXT("AnimBPClassPath: %s"), *AnimBPClassPath);

return true;

}

Now, I am able to navigate to the directories, when searching for maps, I find them, but not able to find any of the assets for my vehicles. Really cant figure out what I am doing wrong, been stuck on this for about two days now… Anyone that has any idea or solution to this problem?

Would be greatly appreciated!

I am 100% certain the assets exists in the mentioned directories, it works when running the game in the editor, but not when packaging the game.

Unreal Engine only packages those assets that are ultimately referenced by Primary Assets (usually levels). This can be viewed using the Reference Viewer utility.
If there are no such dependencies, then the asset will be ignored when packaging.

If you want to pack the asset anyway then add your folder to the Additional Asset Directories to Cook array in the project settings.

Thank you for your reply. I was able to solve the issue, for some reason it seems as (I was cooking the correct content I wanted to include in my project, so that was not the issue).:

TArray<FString> Directories;
IFileManager& FileManager = IFileManager::Get();
FileManager.FindFiles(Directories, *(BaseCarPath / TEXT("*")), false, true);

UE_LOG(LogTemp, Warning, TEXT("BaseCarPath: %s"), *BaseCarPath);
UE_LOG(LogTemp, Warning, TEXT("Found directories: %d"), Directories.Num());

if (Directories.Num() == 0)
{
   UE_LOG(LogTemp, Error, TEXT("No car directories found in %s"), *BaseCarPath);
   return false;
}

Did not work in the packaged build, for some reason FileManager were not able to locate any directories in the BaseCarPath.

When changing to this:

FARFilter DirectoryFilter;
DirectoryFilter.PackagePaths.Add(*BaseCarPath);
DirectoryFilter.bRecursivePaths = true;

TArray<FAssetData> DirectoryAssetDataArray;
AssetRegistry.GetAssets(DirectoryFilter, DirectoryAssetDataArray);

UE_LOG(LogTemp, Warning, TEXT("BaseCarPath: %s"), *BaseCarPath);

TSet<FString> Directories;
for (const FAssetData& AssetData : DirectoryAssetDataArray)
{
    FString AssetPath = AssetData.PackagePath.ToString();
    FString Directory;
    if (AssetPath.Split("/", &Directory, nullptr, ESearchCase::IgnoreCase, ESearchDir::FromEnd))
    {
        Directories.Add(Directory);
    }
}

The packaged version of my game is now able to locate and find the files. I do find it wierd, this is the first time I tried to package my game and there were a lot of bugs in the packaged version that did not occour in the editor. This was the one I were stuck on the longest, I just find it wierd that some things works in the editor and some doesnt. Anyways, I have been able to solve it, thanks for your time!

Hi @PREDALIEN

Will I have that problem with files referenced in a UDeveloperSettings class?

Thank you so much!!

:thinking:
My project doesn’t have such a category in the settings. Is it a plugin?
In any case, it will be easier for you to just check it in a test build (if Reference View doesn’t show promise).

1 Like

It is a custom class


UCLASS(config = Game, defaultconfig, meta = (DisplayName = "SoundsSettings"))
class USoundsSettings : public UDeveloperSettings
{
	GENERATED_BODY()

	UPROPERTY(config, EditAnywhere)
	TSoftObjectPtr<USoundAttenuation> Attenuation;	

.....
};

What happen is some audio files are not registred in my case…
i mean, when i use this function to find assets

AssetRegistryModule.Get().GetAssetsByClass(FTopLevelAssetPath(InPackageName, InAssetName), AssetData);

it only found some files (not all)…

So when a read you post i wonder if i will have the same problema in the packaged game…

I afraid about this custom class now…

i gess the only way to know it is try it and see what happend then.

Thanks for your awnswer @PREDALIEN :heart: