How to create DataAsset with C++ from BluePrint class

Hi

Here is some problem with saving object that created from BluePrint class.

What i have:
Blueprint DataAseet inherited from UDataAsset.

What i need:
Create with C++ same type as my blue print DataAsset object and save to the disk. As same way as inside of UE Editor Misc->Create Data asset.

The Problem:
After asset was created, i have open asset and try to save once again with editor Save icon. Error: TestingAsset.uasset cannot be saved as it has only been partially loaded

In fact on the disk is not my DataAsset class, it’s UDataAsset.

Question:
What proper way to create object from my blue print class? I have no class definition in C++.


// My Blue Print Data Asset class
FString AssetName("/Game/Glass/GlassCombined/DA_TBGlass_Base.DA_TBGlass_Base_C");

UClass* Result = FindObject<UClass>(ANY_PACKAGE, *AssetName);


FString AssetPath = TEXT("../../../../../Projects/PuzzleConstructor3/Content/Dev/");
FString PackagePath = TEXT("/Game/Dev/TestingAsset");

// Create package
UPackage *Package = CreatePackage(nullptr, *PackagePath);
Package->SetFlags(RF_Standalone | RF_Public);

// Create object
auto Test = NewObject<UDataAsset>(Package, Result, *FString("TestingAsset"), EObjectFlags::RF_Public | EObjectFlags::RF_Standalone | RF_Transactional);
FAssetRegistryModule::AssetCreated(Test);

// Save to the disk
bool bSuccess = UPackage::SavePackage(Package, Test, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *FilePath, GWarn, nullptr, true, true, NULL);

Solved. Working code:



FString AssetName2("/Game/Glass/GlassCombined/DA_TBGlass_Base.DA_TBGlass_Base_C");

auto Result = StaticLoadClass(UPrimaryDataAsset::StaticClass(), nullptr, *AssetName2, nullptr, LOAD_None, nullptr);

if (Result != nullptr)
{


FString PackagePathNew = TEXT("/Game/Dev/TestingAsset2");
UPackage *PackageNew = CreatePackage(nullptr, *PackagePathNew);

UObject* Obj = NewObject<UPrimaryDataAsset>(PackageNew, Result, *FString("TestingAsset2"), EObjectFlags::RF_Public | EObjectFlags::RF_Standalone);
FAssetRegistryModule::AssetCreated(Obj);

if (Obj != nullptr)
{
FString const PackageName = PackageNew->GetName();
FString const PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());

UPackage::SavePackage(PackageNew, NULL, RF_Public | RF_Standalone, *PackageFileName , GError, nullptr, false, true, SAVE_NoError);
Obj->MarkPackageDirty();
PackageNew->SetDirtyFlag(true);
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Load class is failed!"));
}


2 Likes

Another nifty way of doing this is using FEditorFileUtils::SaveAssetAs:
https://docs.unrealengine.com/4.27/en-US/API/Editor/UnrealEd/FEditorFileUtils/SaveAssetsAs/

Worked like a charm on the first try for me…