SavePackage does not create uasset on disk

Hello,

I have a strange behaviour I can not solve. I create assets from our level editor at runtime using the following code:

FString mount_point = FPaths::Combine( FPaths::GameSavedDir(), FString( "Player/Levels" ) );

FPackageName::RegisterMountPoint( "/PlayerData/Levels/", mount_point );

USQLevelAsset * level_asset = nullptr;

const auto level_dir = "/PlayerData/Levels";
const auto path_name = FPaths::Combine( level_dir, LevelName.ToString() );
const auto level_file_name = FPaths::GetBaseFilename( path_name );

auto * package = LoadPackage( nullptr, *path_name, LOAD_None );

if ( package != nullptr )
{
    level_asset = FindObject<USQLevelAsset>( package, *level_file_name );
}
else
{
    package = CreatePackage( nullptr, *path_name );
}

if ( level_asset == nullptr )
{
    level_asset = NewObject< USQLevelAsset >( package, USQLevelAsset::StaticClass(), *level_file_name, RF_Public | RF_Standalone );
}

if ( ensure( level_asset != nullptr ) )
{
    level_editor.SaveToLevelAsset( level_asset );

    const auto file_name = FString::Printf( TEXT( "%s%s" ), *path_name, *FPackageName::GetAssetPackageExtension() );

    UPackage::SavePackage( package, /*level_asset*/ nullptr, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *file_name );

    FAssetRegistryModule::AssetCreated( level_asset );

    package->MarkPackageDirty();
}

When I play our game in PIE, and save the asset, it is correctly displayed in the content browser, with a star on the icon, meaning it needs to be saved. But the asset does not exist physically on the disk, I have to save all the assets from the UE editor to have it created in the correct folder.

How can I save the package to disk at the same time? Because the issue I face is that when a player plays the game in standalone, and saves its level, the asset exists in memory, but not in the save folder.

Thanks !

OK I figured out what was wrong.

UPackage::SavePackage expects the filename to be the relative (or absolute?) file path, when I was passing the path of the file in its mounted folder…

There is an example here:

New Uasset from C++

UE4.26 2021.7.12 I meet this question recently,reference this code to save on disk directly

FString MeshName = "TestSM";
FString PackageName = "/Game/" + MeshName;
UPackage* MeshPackage = CreatePackage(nullptr, *PackageName);
UStaticMesh* StaticMesh = NewObject< UStaticMesh >(MeshPackage, FName(*MeshName), RF_Public | RF_Standalone);

//this path is important!!!
FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());
bool bSuccess=UPackage::SavePackage(MeshPackage, StaticMesh, RF_Public | RF_Standalone, *PackageFileName, GError, nullptr, true, true, SAVE_NoError);

1 Like