--- title: FBXAnimation导入逻辑 date: 2023-12-11 11:28:36 excerpt: tags: rating: ⭐ --- # BVHImport插件中的案例 ```c++ UObject* UBVHImportFactory::FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, const FString& FileName, const TCHAR* Parms, FFeedbackContext* Warn, bool& bOutOperationCanceled) { if (!shouldImport) { return nullptr; } bool fileSuccess = BVHFile.ImportData(TCHAR_TO_ANSI(*FileName)); const bool bIsUnattended = (IsAutomatedImport() || FApp::IsUnattended() || IsRunningCommandlet() || GIsRunningUnattendedScript); // Check if it's a re-import if (InParent != nullptr) { UObject* ExistingObject = StaticFindObject(UObject::StaticClass(), InParent, *InName.ToString()); if (ExistingObject) { //reimport逻辑略 } } if (fileSuccess) { UAnimSequence* AnimSequence = NewObject(InParent, InName, Flags & ~EObjectFlags::RF_Transactional); if (Skeleton == NULL) { //创建骨骼资产略 } else { AnimSequence->SetSkeleton(Skeleton);//Skeleton bvhSkel AnimSequence->SetPreviewMesh(PreviewMesh); } ExtractAnimDataFromBVHFile(AnimSequence); return AnimSequence; } return nullptr; } ``` ```c++ void UBVHImportFactory::ExtractAnimDataFromBVHFile(UAnimSequence* AnimSequence) { if (AnimSequence) { // create animation IAnimationDataController& Controller = AnimSequence->GetController(); Controller.OpenBracket(LOCTEXT("ImportBVHAnimation", "Importing BVH Animation")); Controller.ResetModel(); // Write animation data into animation sequence. // Extract transform of hip to create root motion. const FReferenceSkeleton& RefSkeleton = AnimSequence->GetSkeleton()->GetReferenceSkeleton(); const FName RootName = RefSkeleton.GetBoneName(0); const int32 NumOfKeys = BVHFile.Root->FrameOffset.Num(); AnimSequence->ImportFileFramerate = (float)BVHFile.Header.DataRate; AnimSequence->ImportResampleFramerate = BVHFile.Header.DataRate; Controller.SetPlayLength(float(NumOfKeys - 1) / (float)BVHFile.Header.DataRate); Controller.SetFrameRate(FFrameRate(BVHFile.Header.DataRate, 1)); RecursiveReadKeysFromNode(Controller, BVHFile.Root.Get()); Controller.NotifyPopulated(); Controller.CloseBracket(); AnimSequence->AdditiveAnimType = EAdditiveAnimationType::AAT_None; AnimSequence->PostEditChange(); FAssetRegistryModule::AssetCreated(AnimSequence); AnimSequence->MarkPackageDirty(); } } ``` ```c++ void UBVHImportFactory::RecursiveReadKeysFromNode(IAnimationDataController& Controller, FNode* Node) { if (Node) { Controller.AddBoneTrack(Node->Name,false); Controller.SetBoneTrackKeys(Node->Name, Node->FrameOffset, Node->FrameQuat, Node->FrameScale,false); if (Node->Children.Num() > 0) { for (NodePtr Child : Node->Children) { RecursiveReadKeysFromNode(Controller, Child.Get()); } } } } ``` # UAnimSequenceFactory ```c++ UObject* UAnimSequenceFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) { UAnimSequence* AnimSequence = NewObject(InParent, Class, Name, Flags); if (TargetSkeleton) { AnimSequence->SetSkeleton(TargetSkeleton); } if (PreviewSkeletalMesh) { AnimSequence->SetPreviewMesh(PreviewSkeletalMesh); } return AnimSequence; } ``` # UFbxAnimSequenceImportData class UNREALED_API UFbxAnimSequenceImportData : public UFbxAssetImportData UAnimSequence * UnFbx::FFbxImporter::ImportAnimations(USkeleton* Skeleton, UObject* Outer, TArray& SortedLinks, const FString& Name, UFbxAnimSequenceImportData* TemplateImportData, TArray& NodeArray) { EReimportResult::Type UReimportFbxSceneFactory::ReimportSkeletalMesh(void* VoidFbxImporter, TSharedPtr MeshInfo)