bImportBoneTracks
bImportBoneTracks
#Overview
name: bImportBoneTracks
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 20
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of bImportBoneTracks is to control whether bone transform tracks should be imported during animation import in Unreal Engine 5.
This setting variable is primarily used in the animation import system, specifically for importing skeletal animations. It is utilized by the Interchange plugin and the FBX importer in Unreal Engine.
The value of this variable is typically set through import settings or configuration files. It can be found in UFbxAnimSequenceImportData and UInterchangeGenericAnimationPipeline classes.
bImportBoneTracks interacts with other animation import settings such as bImportCustomAttribute, bDeleteExistingNonCurveCustomAttributes, and bRemoveRedundantKeys.
Developers should be aware that setting this variable to false will discard any bone transform tracks during import. This can be useful for importing animations that only contain curve data without bone transformations.
Best practices when using this variable include:
- Keep it enabled (true) for most skeletal animations to ensure proper bone movement.
- Consider disabling it (false) when importing animations that only contain curve data or when you want to preserve existing bone tracks in the target animation.
- When disabled, ensure that other necessary animation data (like custom attributes or curves) are still being imported to maintain the intended animation behavior.
- Be consistent with its usage across related assets to avoid unexpected animation results.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:689, section: [/Script/UnrealEd.FbxAnimSequenceImportData]
- INI Section:
/Script/UnrealEd.FbxAnimSequenceImportData
- Raw value:
True
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:271
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function void FillInterchangeGenericAssetsPipelineFromFbxAnimSequenceImportData
Source code excerpt:
GenericAssetPipeline->AnimationPipeline->bDeleteExistingNonCurveCustomAttributes = AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes;
GenericAssetPipeline->AnimationPipeline->bDoNotImportCurveWithZero = AnimSequenceImportData->bDoNotImportCurveWithZero;
GenericAssetPipeline->AnimationPipeline->bImportBoneTracks = AnimSequenceImportData->bImportBoneTracks;
GenericAssetPipeline->AnimationPipeline->bImportCustomAttribute = AnimSequenceImportData->bImportCustomAttribute;
GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportMeshesInBoneHierarchy = AnimSequenceImportData->bImportMeshesInBoneHierarchy;
GenericAssetPipeline->AnimationPipeline->bRemoveCurveRedundantKeys = AnimSequenceImportData->bRemoveRedundantKeys;
GenericAssetPipeline->AnimationPipeline->bSetMaterialDriveParameterOnCustomAttribute = AnimSequenceImportData->bSetMaterialDriveParameterOnCustomAttribute;
GenericAssetPipeline->AnimationPipeline->bSnapToClosestFrameBoundary = AnimSequenceImportData->bSnapToClosestFrameBoundary;
GenericAssetPipeline->AnimationPipeline->bUse30HzToBakeBoneAnimation = AnimSequenceImportData->bUseDefaultSampleRate;
#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:491
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function UAssetImportData* ConvertToLegacyFbx
Source code excerpt:
DestinationAnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes = GenericAssetPipeline->AnimationPipeline->bDeleteExistingNonCurveCustomAttributes;
DestinationAnimSequenceImportData->bDoNotImportCurveWithZero = GenericAssetPipeline->AnimationPipeline->bDoNotImportCurveWithZero;
DestinationAnimSequenceImportData->bImportBoneTracks = GenericAssetPipeline->AnimationPipeline->bImportBoneTracks;
DestinationAnimSequenceImportData->bImportCustomAttribute = GenericAssetPipeline->AnimationPipeline->bImportCustomAttribute;
DestinationAnimSequenceImportData->bImportMeshesInBoneHierarchy = GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportMeshesInBoneHierarchy;
DestinationAnimSequenceImportData->bPreserveLocalTransform = false;
DestinationAnimSequenceImportData->bRemoveRedundantKeys = GenericAssetPipeline->AnimationPipeline->bRemoveCurveRedundantKeys;
DestinationAnimSequenceImportData->bSetMaterialDriveParameterOnCustomAttribute = GenericAssetPipeline->AnimationPipeline->bSetMaterialDriveParameterOnCustomAttribute;
DestinationAnimSequenceImportData->bSnapToClosestFrameBoundary = GenericAssetPipeline->AnimationPipeline->bSnapToClosestFrameBoundary;
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Animation/InterchangeAnimSequenceFactory.cpp:424
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function void RetrieveAnimationPayloads
Source code excerpt:
const bool bShouldTransact = bIsReimporting;
bool bImportBoneTracks = false;
AnimSequenceFactoryNode->GetCustomImportBoneTracks(bImportBoneTracks);
if (bImportBoneTracks)
{
//Get the sample rate, default to 30Hz in case the attribute is missing
double SampleRate = 30.0;
AnimSequenceFactoryNode->GetCustomImportBoneTracksSampleRate(SampleRate);
double RangeStart = 0.0;
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Animation/InterchangeAnimSequenceFactory.cpp:1053
Scope (from outer to inner):
file
function UInterchangeFactoryBase::FImportAssetResult UInterchangeAnimSequenceFactory::ImportAsset_Async
Source code excerpt:
const bool bIsReImport = (Arguments.ReimportObject != nullptr);
bool bImportBoneTracks = false;
AnimSequenceFactoryNode->GetCustomImportBoneTracks(bImportBoneTracks);
if (bImportBoneTracks)
{
USkeleton* Skeleton = AnimSequence->GetSkeleton();
check(Skeleton);
TMap<const UInterchangeSceneNode*, TFuture<TOptional<UE::Interchange::FAnimationPayloadData>>> AnimationPayloads;
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Animation/InterchangeAnimSequenceFactory.cpp:1286
Scope (from outer to inner):
file
function UInterchangeFactoryBase::FImportAssetResult UInterchangeAnimSequenceFactory::EndImportAsset_GameThread
Source code excerpt:
double SampleRate = 30.0;
bool bImportBoneTracks = false;
if (AnimSequenceFactoryNode->GetCustomImportBoneTracks(bImportBoneTracks) && bImportBoneTracks)
{
if (AnimSequenceFactoryNode->GetCustomImportBoneTracksSampleRate(SampleRate))
{
FrameRate = UE::Interchange::Animation::ConvertSampleRatetoFrameRate(SampleRate);
}
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Animation/InterchangeAnimSequenceFactory.cpp:1407
Scope (from outer to inner):
file
function bool UInterchangeAnimSequenceFactory::IsBoneTrackAnimationValid
Source code excerpt:
double SampleRate = 30.0;
bool bImportBoneTracks = false;
if (AnimSequenceFactoryNode->GetCustomImportBoneTracks(bImportBoneTracks) && bImportBoneTracks)
{
if (AnimSequenceFactoryNode->GetCustomImportBoneTracksSampleRate(SampleRate))
{
FrameRate = UE::Interchange::Animation::ConvertSampleRatetoFrameRate(SampleRate);
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericAnimationPipeline.cpp:30
Scope (from outer to inner):
file
function bool UInterchangeGenericAnimationPipeline::CanEditChange
Source code excerpt:
if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UInterchangeGenericAnimationPipeline, FrameImportRange))
{
return ParentVal && bImportAnimations && bImportBoneTracks && AnimationRange == EInterchangeAnimationRange::SetRange;
}
return ParentVal;
}
#endif
void UInterchangeGenericAnimationPipeline::AdjustSettingsForContext(EInterchangePipelineContext ImportType, TObjectPtr<UObject> ReimportAsset)
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericAnimationPipeline.cpp:458
Scope (from outer to inner):
file
function void UInterchangeGenericAnimationPipeline::CreateAnimSequenceFactoryNode
Source code excerpt:
bool bTimeRangeIsValid = false;
if (bImportBoneTracks)
{
if (const UInterchangeSourceNode* SourceNode = UInterchangeSourceNode::GetUniqueInstance(BaseNodeContainer))
{
int32 Numerator, Denominator;
if (!bUse30HzToBakeBoneAnimation && CustomBoneAnimationSampleRate == 0 && SourceNode->GetCustomSourceFrameRateNumerator(Numerator))
{
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericAnimationPipeline.cpp:584
Scope (from outer to inner):
file
function void UInterchangeGenericAnimationPipeline::CreateAnimSequenceFactoryNode
Source code excerpt:
}
AnimSequenceFactoryNode->SetCustomImportBoneTracks(bImportBoneTracks);
AnimSequenceFactoryNode->SetCustomImportBoneTracksSampleRate(SampleRate);
if (bTimeRangeIsValid)
{
AnimSequenceFactoryNode->SetCustomImportBoneTracksRangeStart(StartTime);
AnimSequenceFactoryNode->SetCustomImportBoneTracksRangeStop(StopTime);
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Public/InterchangeGenericAnimationPipeline.h:56
Scope (from outer to inner):
file
class class UInterchangeGenericAnimationPipeline : public UInterchangePipelineBase
Source code excerpt:
/** Import bone transform tracks. If false, this will discard any bone transform tracks.*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animations", meta = (EditCondition = "bImportAnimations"))
bool bImportBoneTracks = true;
/** Determines which animation range to import: the range defined at export, the range of frames with animation, or a manually defined range. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animations", meta = (EditCondition = "bImportAnimations && bImportBoneTracks", DisplayName = "Animation Length"))
EInterchangeAnimationRange AnimationRange = EInterchangeAnimationRange::Timeline;
/** The frame range used when the Animation Length setting is set to Set Range. */
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxAnimSequenceImportData.h:87
Scope (from outer to inner):
file
class class UFbxAnimSequenceImportData : public UFbxAssetImportData
Source code excerpt:
/** Import bone transform tracks. If false, this will discard any bone transform tracks. (useful for curves only animations)*/
UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = ImportSettings)
bool bImportBoneTracks;
/** Set Material Curve Type for all custom attributes that exists */
UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = ImportSettings, meta = (EditCondition = "bImportCustomAttribute", DisplayName="Set Material Curve Type"))
bool bSetMaterialDriveParameterOnCustomAttribute;
/** Whether to automatically add curve metadata to an animation's skeleton. If this is disabled, curve metadata will be added to skeletal meshes for morph targets, but no metadata entry will be created for general curves. */
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimSequenceImportData.cpp:7
Scope (from outer to inner):
file
function UFbxAnimSequenceImportData::UFbxAnimSequenceImportData
Source code excerpt:
, bImportMeshesInBoneHierarchy(true)
, bImportCustomAttribute(true)
, bImportBoneTracks(true)
, bAddCurveMetadataToSkeleton(true)
, bRemoveRedundantKeys(true)
, bDoNotImportCurveWithZero(true)
{
FrameImportRange.Min = 0;
FrameImportRange.Max = 0;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimSequenceImportData.cpp:88
Scope (from outer to inner):
file
function void UFbxAnimSequenceImportData::CopyAnimationValues
Source code excerpt:
bDeleteExistingNonCurveCustomAttributes = Other->bDeleteExistingNonCurveCustomAttributes;
bDoNotImportCurveWithZero = Other->bDoNotImportCurveWithZero;
bImportBoneTracks = Other->bImportBoneTracks;
bImportCustomAttribute = Other->bImportCustomAttribute;
bImportMeshesInBoneHierarchy = Other->bImportMeshesInBoneHierarchy;
bPreserveLocalTransform = Other->bPreserveLocalTransform;
bRemoveRedundantKeys = Other->bRemoveRedundantKeys;
bSetMaterialDriveParameterOnCustomAttribute = Other->bSetMaterialDriveParameterOnCustomAttribute;
bAddCurveMetadataToSkeleton = Other->bAddCurveMetadataToSkeleton;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:513
Scope (from outer to inner):
file
namespace UnFbx
function void ApplyImportUIToImportOptions
Source code excerpt:
InOutImportOptions.bDeleteExistingCustomAttributeCurves = ImportUI->AnimSequenceImportData->bDeleteExistingCustomAttributeCurves;
InOutImportOptions.bDeleteExistingNonCurveCustomAttributes = ImportUI->AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes;
InOutImportOptions.bImportBoneTracks = ImportUI->AnimSequenceImportData->bImportBoneTracks;
InOutImportOptions.bSetMaterialDriveParameterOnCustomAttribute = ImportUI->AnimSequenceImportData->bSetMaterialDriveParameterOnCustomAttribute;
InOutImportOptions.bAddCurveMetadataToSkeleton = ImportUI->AnimSequenceImportData->bAddCurveMetadataToSkeleton;
InOutImportOptions.MaterialCurveSuffixes = ImportUI->AnimSequenceImportData->MaterialCurveSuffixes;
}
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1790
Scope (from outer to inner):
file
lambda-function
Source code excerpt:
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt AnimationRange"), CaptureImportOptions->AnimationRange.ToString()));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DoNotImportCurveWithZero"), CaptureImportOptions->bDoNotImportCurveWithZero));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt ImportBoneTracks"), CaptureImportOptions->bImportBoneTracks));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt ImportCustomAttribute"), CaptureImportOptions->bImportCustomAttribute));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingCustomAttributeCurves"), CaptureImportOptions->bDeleteExistingCustomAttributeCurves));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingNonCurveCustomAttributes"), CaptureImportOptions->bDeleteExistingNonCurveCustomAttributes));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt PreserveLocalTransform"), CaptureImportOptions->bPreserveLocalTransform));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt RemoveRedundantKeys"), CaptureImportOptions->bRemoveRedundantKeys));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt Resample"), CaptureImportOptions->bResample));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportFactory.cpp:1873
Scope (from outer to inner):
file
function UObject* UFbxSceneImportFactory::ImportOneSkeletalMesh
Source code excerpt:
bool Old_bBakePivotInVertex = GlobalImportSettings->bBakePivotInVertex;
GlobalImportSettings->bBakePivotInVertex = false;
GlobalImportSettings->bImportBoneTracks = true;
//if (GlobalImportSettings->bBakePivotInVertex && RootNodeInfo->AttributeInfo->PivotNodeUid == INVALID_UNIQUE_ID)
//{
//GlobalImportSettings->bBakePivotInVertex = false;
//}
// check if there is LODGroup for this skeletal mesh
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/ReimportFbxSceneFactory.cpp:1098
Scope (from outer to inner):
file
function EReimportResult::Type UReimportFbxSceneFactory::ImportSkeletalMesh
Source code excerpt:
bool Old_bBakePivotInVertex = GlobalImportSettings->bBakePivotInVertex;
GlobalImportSettings->bBakePivotInVertex = false;
GlobalImportSettings->bImportBoneTracks = true;
//if (GlobalImportSettings->bBakePivotInVertex && MeshInfo->PivotNodeUid == INVALID_UNIQUE_ID)
//{
//GlobalImportSettings->bBakePivotInVertex = false;
//}
TArray< TArray<FbxNode*>* > SkelMeshArray;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/ReimportFbxSceneFactory.cpp:1296
Scope (from outer to inner):
file
function EReimportResult::Type UReimportFbxSceneFactory::ReimportSkeletalMesh
Source code excerpt:
bool Old_bBakePivotInVertex = GlobalImportSettings->bBakePivotInVertex;
GlobalImportSettings->bBakePivotInVertex = false;
GlobalImportSettings->bImportBoneTracks = true;
//if (GlobalImportSettings->bBakePivotInVertex && MeshInfo->PivotNodeUid == INVALID_UNIQUE_ID)
//{
//GlobalImportSettings->bBakePivotInVertex = false;
//}
TArray<FbxNode*> OutSkeletalMeshArray;
EReimportResult::Type ReimportResult = EReimportResult::Succeeded;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp:1848
Scope (from outer to inner):
file
function bool UnFbx::FFbxImporter::ImportAnimation
Source code excerpt:
// import animation
if (ImportOptions->bImportBoneTracks)
{
FbxNode* SkeletalMeshRootNode = NodeArray.Num() > 0 ? NodeArray[0] : nullptr;
ImportBoneTracks(Skeleton, AnimImportSettings, SkeletalMeshRootNode, ResampleRate, TransformDebugData, TotalNumKeys, bReimport);
AnimationTransformDebug::OutputAnimationTransformDebugData(TransformDebugData, TotalNumKeys, RefSkeleton);
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Public/FbxImporter.h:200
Scope (from outer to inner):
file
namespace UnFbx
Source code excerpt:
bool bDeleteExistingCustomAttributeCurves;
bool bDeleteExistingNonCurveCustomAttributes;
bool bImportBoneTracks;
bool bSetMaterialDriveParameterOnCustomAttribute;
bool bAddCurveMetadataToSkeleton;
bool bRemoveRedundantKeys;
bool bDoNotImportCurveWithZero;
bool bResetToFbxOnMaterialConflict;
TArray<FString> MaterialCurveSuffixes;