How to import assets automatically through code and what is UPackage?

I am trying to import some assets in editor automatically through code. I found some methods like FAssetToolsModule::ImportAssets, so I do it straight forward, for example, I have a source fbx animation file and its textures in “C:/MyProject/Content/Raw/dog.fbx” and “C:/MyProject/Content/Raw/dog_dif.png”, and I want to import it as uassets including material, animation, skinnedmesh and texture to folder “C:/MyProject/Content/Imported/Dog”, I do:

FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
AssetToolsModule.Get().ImportAssets(TEXT("C:/MyProject/Content/Raw/dog.fbx"), TEXT("C:/MyProject/Content/Imported/Dog"));

Then I will get an error said “LongPackageNameToFilename failed to convert ‘C_/MyProject/Content/Imported/Dog/dog_dif’. Path does not map to any roots.”. I searched related codes and examples that I noticed that when importing some resources to project, people always use CreatePackage to create a UPackage first, but I can’t figure out what a UPackage actually is. It seems that the package name must start with “/Game/”, what is that directory? is “/Game/” stands for the “Content” folder path? I think the thing I should do is create a UPackage in the destination folder, and then include the source files into that package, and then import the package by proper factory, but I can’t find some reference showing how to do that. And I really want to know how to create a UPackage and connect it with source files.

2 Likes

Answered by myself for people after, I am still not clear what a UPackage is but I fixed my code to work.
The second string parameter refers to the destination path must starts with “/Game/”. “/Game/” refers to the path to Contents folder so the code will work by changing it to:

		FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
		AssetToolsModule.Get().ImportAssets(TEXT("C:/MyProject/Content/Raw/dog.fbx"), TEXT("/Game/Imported/Dog"));

There will be a prompt to set import arguments, so I changed it to UAssetToolsImpl::ImportAssetsAutomated.

		TArray<FString> filesToImport;
		FString srcPath = TEXT("C:/MyProject/Content/Raw/dog.fbx");
		srcPath = srcPath.Replace(TEXT("\\"), TEXT("/"));
		filesToImport.Add(srcPath);

		UAutomatedAssetImportData* importData = NewObject<UAutomatedAssetImportData>();
		importData->bReplaceExisting = true;
		importData->DestinationPath = TEXT("C:/MyProject/Content/Imported/Dog");
		importData->Filenames = filesToImport;

		FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
		auto importedAssets = AssetToolsModule.Get().ImportAssetsAutomated(importData);

You can also add other files like texture and normal map to the importData’s Filenames array to import them together.

By the way, this function must be called within GameThread, if you are doing it in a sub thread you can tries to deal it with methods in this post:

Hope this helps someone.

2 Likes

the destination path must start with “/Game/” too or unreal generate an expection.
So a valid path can be “/Game/Imported”, without specify the absolute path

1 Like

you very much for the heads up. I was able to port the code to blueprint within an Editor Utility Widget (UE4.26)

Here is what it looks like: