Automated Animation Import

I’m looking for examples of how to import animations from native and not finding what I’m looking for.

I believe the older way would have been via something like:

bool bImportMorphTracks = true;

UFbxAnimSequenceImportData* AnimationSequenceData = nullptr;

FacialAnimation = UEditorEngine::ImportFbxAnimation(Skeleton, AnimationOuter, AnimationSequenceData, *StagedFBXFileName, *AssetName, bImportMorphTracks);

(This method isn’t working for me. But it’s not using the “drag drop” import method the editor uses.

The newer method looks more like this (using Interchange)

UAutomatedAssetImportData* importData = NewObject<UAutomatedAssetImportData>();

importData->bReplaceExisting = true;

importData->DestinationPath = Directory;

importData->Filenames = ImportFiles;

FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>(“AssetTools”);

AssetToolsModule.Get().ImportAssetsAutomated(ImportData);

The newer API doesn’t seem to let me specify a skeleton to import with like the dialog

[Image Removed]

What is the proper way to do bulk importing of animations with a reference skeleton via native?

Thank you!

JB

Steps to Reproduce

Hi Jason,

Unfortunately, none of the helpers using the legacy FBX importer to import different specific assets, like UEditorEngine::ImportFbxAnimation, has been updated to use Interchange when it is enabled. This is on our todo list but we do not have any ETA on when they will be updated.

Additionally, the call to ImportAssetsAutomated does not work as Interchange does not detect the skeleton to use.

I looked into the code and it looks like you need to do a little bit more for UEditorEngine::ImportFbxAnimation to work. Here is what I think would work:

`// Assuming that bImportMorphTracks, Skeleton and AssetName are set
UFbxAnimSequenceImportData* ImportData = NewObject();
FFbxImporter* FbxImporter = UnFbx::FFbxImporter::GetInstance();
UnFbx::FBXImportOptions* ImportOptions = FbxImporter->GetImportOptions();
UnFbx::FBXImportOptions::ResetOptions(ImportOptions);
ImportOptions->bImportAnimations = true;
ImportOptions->bImportMaterials = true;
ImportOptions->bImportTextures = true;
ImportOptions->bImportBoneTracks = true;
ImportOptions->bImportCustomAttribute = true;
ImportOptions->bUsedAsFullName = true;
ImportOptions->bConvertScene = true;
ImportOptions->bAddCurveMetadataToSkeleton = true;
ImportOptions->bDoNotImportCurveWithZero = true;
ImportOptions->bRemoveRedundantKeys = true;
ImportOptions->bResample = true;
ImportOptions->MaterialCurveSuffixes.Emplace(TEXT(“_mat”));
ImportOptions->ImportType = FBXIT_Animation;
ImportOptions->SkeletonForAnimation = Skeleton;

UAnimSequence* AnimSequence = UEditorEngine::ImportFbxAnimation(Skeleton, (UObject*)GetTransientPackage(), ImportData, FbxFileName, AssetName, bImportMorphTracks);`With Interchange enabled, you could try the pseudo code below. It should emulate what ImportFbxAnimation is doing but with Interchange. Not optimal, but hopefully, this will help you with what you are trying to do.

`// Use the DefaultAssetsPipeline asset as a base
static const FSoftObjectPath GenericPipelinePath(TEXT(“/Interchange/Pipelines/DefaultAssetsPipeline.DefaultAssetsPipeline”));
UInterchangeGenericAssetsPipeline* AssetPipeline = Cast(GenericPipelinePath.TryLoad());

// Duplicate it in order to modify it locally
UInterchangeGenericAssetsPipeline* DuplicatePipeline = DuplicateObject(AssetPipeline, GetTransientPackageAsObject());

// Set your duplicate to only import animation with a given skeleton
// Disable what is not desired
DuplicatePipeline->MaterialPipeline->bImportMaterials = false;
DuplicatePipeline->MaterialPipeline->TexturePipeline->bImportTextures = false;
DuplicatePipeline->MeshPipeline->bImportStaticMeshes = false;
// Make sure only animation is imported.
DuplicatePipeline->AnimationPipeline->bImportAnimations = true;
DuplicatePipeline->MeshPipeline->bImportSkeletalMeshes = true;
DuplicatePipeline->MeshPipeline->bImportMorphTargets = [false|true];
DuplicatePipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportOnlyAnimations = true;
DuplicatePipeline->CommonSkeletalMeshesAndAnimationsProperties->Skeleton = Skeleton;

// Create an Interchange pipeline override to set it as an option to your UAssetImportTask.
// Interchange will collect those overrides and use them to import
UInterchangePipelineStackOverride StackOverride = NewObject();
StackOverride->AddPipeline(DuplicatePipeline);

UAssetImportTask* ImportTask = NewObject();
ImportTask->bAutomated = true;
ImportTask->Options = StackOverride;

// Set up the other members of ImportStack based on your needs, i.e. DestinationPath, DestinationName, etc…

for(FString& Filename : Filenames)
{
ImportTask->Filename = Filename;
IAssetTools::Get().ImportAssetTasks({ImportTask});
}` Let me know how it goes.

Regards,

Jean-Luc.

Hi Evelyn,

The ImportRotation option is used for the skeletal mesh. Since this is an animation import, this option has no effect.

You will have to apply it to the resulting AnimSequence.

Regards,

Jean-Luc

Hi Jean-Luc,

Thank you! We used the FbxImporter code, and the imports are now working.

How would we add an Offset Rotation using this method? I tried adding ImportRotation to the ImportOptions, but it didn’t seem to update the imported animation’s rotation.

Best,

Evelyn