AnimationLength

AnimationLength

#Overview

name: AnimationLength

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 37 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of AnimationLength is to store the duration of an animation sequence in frames. It is used primarily in the animation and sequencer systems of Unreal Engine 5 to determine the length of animation playback and to properly set up animation sections in sequencer tracks.

AnimationLength is utilized by various Unreal Engine subsystems, plugins, and modules, including:

  1. Animation system
  2. Sequencer
  3. FBX import/export
  4. Geometry Cache
  5. Niagara
  6. Control Rig
  7. Hair Strands

The value of AnimationLength is typically set when importing animations or creating animation sections in sequencer tracks. It is often calculated by multiplying the animation’s duration in seconds by the frame rate.

AnimationLength frequently interacts with other variables such as StartFrame, EndFrame, FrameRate, and PlayRate to determine the exact timing and playback of animations.

Developers should be aware that AnimationLength is crucial for proper timing in animation playback and sequencer tracks. It’s important to ensure that this value is accurately set and maintained, especially when dealing with custom animation import/export processes or when manipulating animation data programmatically.

Best practices when using AnimationLength include:

  1. Always calculate it based on the actual animation data and the project’s frame rate to ensure accuracy.
  2. When modifying animations or creating custom animation systems, make sure to update AnimationLength accordingly.
  3. Be mindful of how AnimationLength interacts with looping animations and adjust your logic accordingly.
  4. When working with the FBX import/export system, pay attention to how AnimationLength is set and used to ensure proper animation data transfer.
  5. In sequencer tracks, use AnimationLength to properly size and position animation sections.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:683, section: [/Script/UnrealEd.FbxAnimSequenceImportData]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Animation/ControlRig/Source/ControlRigEditor/Private/Sequencer/ControlRigParameterTrackEditor.cpp:1211

Scope (from outer to inner):

file
function     void FControlRigParameterTrackEditor::BakeInvertedPose

Source code excerpt:


	UnFbx::FLevelSequenceAnimTrackAdapter AnimTrackAdapter(ParentSequencer.Get(), MovieScene, RootToLocalTransform);
	int32 AnimationLength = AnimTrackAdapter.GetLength();
	FScopedSlowTask Progress(AnimationLength, LOCTEXT("BakingToControlRig_SlowTask", "Baking To Control Rig..."));
	Progress.MakeDialog(true);

	auto DelegateHandle = InControlRig->OnPreAdditiveValuesApplication_AnyThread().AddLambda([](UControlRig* InControlRig, const FName& InEventName)
	{
		InControlRig->InvertInputPose();
	});

#Loc: <Workspace>/Engine/Plugins/Experimental/ChaosCaching/Source/ChaosCaching/Private/Chaos/Sequencer/MovieSceneChaosCacheTrack.cpp:35

Scope (from outer to inner):

file
function     UMovieSceneSection* UMovieSceneChaosCacheTrack::AddNewAnimation

Source code excerpt:

		if(ChaosCache && ChaosCache->CacheCollection)
		{
			const FFrameTime AnimationLength = ChaosCache->CacheCollection->GetMaxDuration() * GetTypedOuter<UMovieScene>()->GetTickResolution();
			const int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
			NewSection->InitialPlacementOnRow(AnimationSections, KeyTime, IFrameNumber, INDEX_NONE);
			
			NewSection->Params.CacheCollection = ChaosCache->CacheCollection;
		}
	}

#Loc: <Workspace>/Engine/Plugins/Experimental/GeometryCollectionPlugin/Source/GeometryCollectionTracks/Private/MovieSceneGeometryCollectionSection.cpp:72

Scope (from outer to inner):

file
function     TOptional<TRange<FFrameNumber> > UMovieSceneGeometryCollectionSection::GetAutoSizeRange

Source code excerpt:

	FFrameRate FrameRate = GetTypedOuter<UMovieScene>()->GetTickResolution();

	FFrameTime AnimationLength = Params.GetSequenceLength() * FrameRate;

	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + AnimationLength.FrameNumber);
}


void UMovieSceneGeometryCollectionSection::TrimSection(FQualifiedFrameTime TrimTime, bool bTrimLeft, bool bDeleteKeys)
{
	SetFlags(RF_Transactional);

#Loc: <Workspace>/Engine/Plugins/FX/NiagaraSimCaching/Source/NiagaraSimCaching/Private/Niagara/Sequencer/MovieSceneNiagaraCacheTemplate.cpp:113

Scope (from outer to inner):

file
function     float MapTimeToAnimation

Source code excerpt:

		
		const float SequenceLength = Section.Params.SectionStretchMode == ENiagaraSimCacheSectionStretchMode::TimeDilate ? InFrameRate.AsSeconds(SectionEndTime - SectionStartTime) : ComponentDuration;
		const FFrameTime AnimationLength = SequenceLength * InFrameRate;
		const int32 LengthInFrames = AnimationLength.FrameNumber.Value + static_cast<int>(AnimationLength.GetSubFrame() + 0.5f) + 1;
	
		//we only play end if we are not looping, and assuming we are looping if Length is greater than default length;
		const bool bLooping = (SectionEndTime.Value - SectionStartTime.Value + BaseParams.StartFrameOffset + BaseParams.EndFrameOffset) > LengthInFrames;

		InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime - 1));

#Loc: <Workspace>/Engine/Plugins/FX/NiagaraSimCaching/Source/NiagaraSimCaching/Private/Niagara/Sequencer/MovieSceneNiagaraCacheTrack.cpp:33

Scope (from outer to inner):

file
function     UMovieSceneSection* UMovieSceneNiagaraCacheTrack::AddNewAnimation

Source code excerpt:

	UMovieSceneNiagaraCacheSection* NewSection = Cast<UMovieSceneNiagaraCacheSection>(CreateNewSection());
	{
		//const FFrameTime AnimationLength = NiagaraCache->CacheCollection->GetMaxDuration() * GetTypedOuter<UMovieScene>()->GetTickResolution();
		//const int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
		//NewSection->InitialPlacementOnRow(AnimationSections, KeyTime, IFrameNumber, INDEX_NONE);
	}

	AddSection(*NewSection);

	return NewSection;

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:248

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     void FillInterchangeGenericAssetsPipelineFromFbxAnimSequenceImportData

Source code excerpt:

		}

		switch (AnimSequenceImportData->AnimationLength)
		{
		case EFBXAnimationLengthImportType::FBXALIT_ExportedTime:
		{
			GenericAssetPipeline->AnimationPipeline->AnimationRange = EInterchangeAnimationRange::Timeline;
			break;
		}

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:472

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     UAssetImportData* ConvertToLegacyFbx

Source code excerpt:

				case EInterchangeAnimationRange::Timeline:
				{
					DestinationAnimSequenceImportData->AnimationLength = EFBXAnimationLengthImportType::FBXALIT_ExportedTime;
					break;
				}
				case EInterchangeAnimationRange::Animated:
				{
					DestinationAnimSequenceImportData->AnimationLength = EFBXAnimationLengthImportType::FBXALIT_AnimatedKey;
					break;
				}
				case EInterchangeAnimationRange::SetRange:
				{
					DestinationAnimSequenceImportData->AnimationLength = EFBXAnimationLengthImportType::FBXALIT_SetRange;
					break;
				}
				}
				DestinationAnimSequenceImportData->bAddCurveMetadataToSkeleton = GenericAssetPipeline->AnimationPipeline->bAddCurveMetadataToSkeleton;
				DestinationAnimSequenceImportData->bDeleteExistingCustomAttributeCurves = GenericAssetPipeline->AnimationPipeline->bDeleteExistingCustomAttributeCurves;
				DestinationAnimSequenceImportData->bDeleteExistingMorphTargetCurves = GenericAssetPipeline->AnimationPipeline->bDeleteExistingMorphTargetCurves;

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheSection.cpp:112

Scope (from outer to inner):

file
function     TOptional<TRange<FFrameNumber> > UMovieSceneGeometryCacheSection::GetAutoSizeRange

Source code excerpt:

{
	FFrameRate FrameRate = GetTypedOuter<UMovieScene>()->GetTickResolution();
	FFrameTime AnimationLength = Params.GetSequenceLength() * FrameRate;
	int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f);

	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + IFrameNumber + 1);
}


void UMovieSceneGeometryCacheSection::TrimSection(FQualifiedFrameTime TrimTime, bool bTrimLeft, bool bDeleteKeys)

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.cpp:131

Scope (from outer to inner):

file
function     float FMovieSceneGeometryCacheSectionTemplateParameters::MapTimeToAnimation

Source code excerpt:

{
	const float SequenceLength = ComponentDuration;
	const FFrameTime AnimationLength = SequenceLength * InFrameRate;
	const int32 LengthInFrames = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
	//we only play end if we are not looping, and assuming we are looping if Length is greater than default length;
	const bool bLooping = (SectionEndTime.Value - SectionStartTime.Value + StartFrameOffset + EndFrameOffset) > LengthInFrames;

	InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime - 1));

	const float SectionPlayRate = PlayRate;

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTrack.cpp:35

Scope (from outer to inner):

file
function     UMovieSceneSection* UMovieSceneGeometryCacheTrack::AddNewAnimation

Source code excerpt:

	UMovieSceneGeometryCacheSection* NewSection = Cast<UMovieSceneGeometryCacheSection>(CreateNewSection());
	{
		FFrameTime AnimationLength = GeomCacheComp->GetDuration()* GetTypedOuter<UMovieScene>()->GetTickResolution();
		int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
		NewSection->InitialPlacementOnRow(AnimationSections, KeyTime, IFrameNumber, INDEX_NONE);
		
		NewSection->Params.GeometryCacheAsset = (GeomCacheComp->GetGeometryCache());
	}

	AddSection(*NewSection);

#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsCore/Private/MovieSceneGroomCacheSection.cpp:37

Scope (from outer to inner):

file
function     TOptional<TRange<FFrameNumber> > UMovieSceneGroomCacheSection::GetAutoSizeRange

Source code excerpt:

{
	FFrameRate FrameRate = GetTypedOuter<UMovieScene>()->GetTickResolution();
	FFrameTime AnimationLength = Params.GetSequenceLength() * FrameRate;
	int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f);

	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + IFrameNumber + 1);
}


void UMovieSceneGroomCacheSection::TrimSection(FQualifiedFrameTime TrimTime, bool bTrimLeft, bool bDeleteKeys)

#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsCore/Private/MovieSceneGroomCacheTemplate.cpp:126

Scope (from outer to inner):

file
function     float FMovieSceneGroomCacheSectionTemplateParameters::MapTimeToAnimation

Source code excerpt:

{
	const float SequenceLength = ComponentDuration;
	const FFrameTime AnimationLength = SequenceLength * InFrameRate;
	const int32 LengthInFrames = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
	//we only play end if we are not looping, and assuming we are looping if Length is greater than default length;
	const bool bLooping = (SectionEndTime.Value - SectionStartTime.Value + StartFrameOffset + EndFrameOffset) > LengthInFrames;

	InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime - 1));

	const float SectionPlayRate = PlayRate;

#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsCore/Private/MovieSceneGroomCacheTrack.cpp:33

Scope (from outer to inner):

file
function     UMovieSceneSection* UMovieSceneGroomCacheTrack::AddNewAnimation

Source code excerpt:

	UMovieSceneGroomCacheSection* NewSection = Cast<UMovieSceneGroomCacheSection>(CreateNewSection());
	{
		FFrameTime AnimationLength = GroomComp->GetGroomCacheDuration() * GetTypedOuter<UMovieScene>()->GetTickResolution();
		int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
		NewSection->InitialPlacementOnRow(AnimationSections, KeyTime, IFrameNumber, INDEX_NONE);
		
		NewSection->Params.GroomCache = GroomComp->GetGroomCache();
	}

	AddSection(*NewSection);

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:1712

Scope (from outer to inner):

file
function     BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F

Source code excerpt:

						break;
					}
					float AnimationLength = AnimSequence->GetPlayLength();
					if (!FMath::IsNearlyEqual(AnimationLength, ExpectedResult.ExpectedPresetsDataFloat[0], 0.001f))
					{
						ExecutionInfo.AddError(FString::Printf(TEXT("%s [%f seconds but expected %f]"),
							*FormatedMessageErrorPrefix, AnimationLength, ExpectedResult.ExpectedPresetsDataFloat[0]));
					}
				}
			}
			break;
			case Animation_CustomCurve_KeyValue:
			{

#Loc: <Workspace>/Engine/Source/Editor/MovieSceneTools/Private/MovieSceneToolHelpers.cpp:3812

Scope (from outer to inner):

file
function     bool MovieSceneToolHelpers::BakeToSkelMeshToCallbacks

Source code excerpt:

	int32 LocalStartFrame = AnimTrackAdapter.GetLocalStartFrame();
	int32 StartFrame = AnimTrackAdapter.GetStartFrame();
	int32 AnimationLength = AnimTrackAdapter.GetLength();
	float FrameRate = AnimTrackAdapter.GetFrameRate();
	float DeltaTime = 1.0f / FrameRate;
	FFrameRate SampleRate = MovieScene->GetDisplayRate();


	//If we are running with a live link track we need to do a few things.

#Loc: <Workspace>/Engine/Source/Editor/MovieSceneTools/Private/MovieSceneToolHelpers.cpp:3871

Scope (from outer to inner):

file
function     bool MovieSceneToolHelpers::BakeToSkelMeshToCallbacks

Source code excerpt:

	StartCallback.ExecuteIfBound();

	for (int32 FrameCount = 1; FrameCount <= AnimationLength; ++FrameCount)
	{
		int32 LocalIndex = LocalStartFrame + FrameCount;
		FFrameNumber LocalFrame(LocalIndex);
		TickFrame(LocalFrame, DeltaTime, MovieScene, AnimTrackAdapter, BakeHelpers, SkelMeshComps, LiveLinkClient, SourceAndMode);
		TickCallback.ExecuteIfBound(DeltaTime, LocalFrame);
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxAnimSequenceImportData.h:44

Scope (from outer to inner):

file
class        class UFbxAnimSequenceImportData : public UFbxAssetImportData

Source code excerpt:

	/** Which animation range to import. The one defined at Exported, at Animated time or define a range manually */
	UPROPERTY(EditAnywhere, Category = ImportSettings, config, meta = (DisplayName = "Animation Length"))
	TEnumAsByte<enum EFBXAnimationLengthImportType> AnimationLength;

	/** Start frame when Set Range is used in Animation Length */
	UPROPERTY()
	int32	StartFrame_DEPRECATED;

	/** End frame when Set Range is used in Animation Length  */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSceneImportOptionsSkeletalMesh.h:75

Scope (from outer to inner):

file
class        class UFbxSceneImportOptionsSkeletalMesh : public UObject

Source code excerpt:

	/** Type of asset to import from the FBX file */
	UPROPERTY(EditAnywhere, Category = Animation, config, meta = (DisplayName = "Animation Length"))
	TEnumAsByte<enum EFBXAnimationLengthImportType> AnimationLength;

	/** Frame range used when Set Range is used in Animation Length */
	UPROPERTY(EditAnywhere, Category = Animation, meta = (UIMin = 0, ClampMin = 0))
	FInt32Interval FrameImportRange;

	/** Enable this option to use default sample rate for the imported animation at 30 frames per second */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimSequenceImportData.cpp:83

Scope (from outer to inner):

file
function     void UFbxAnimSequenceImportData::CopyAnimationValues

Source code excerpt:

		return;
	}
	AnimationLength = Other->AnimationLength;
	bDeleteExistingCustomAttributeCurves = Other->bDeleteExistingCustomAttributeCurves;
	bDeleteExistingMorphTargetCurves = Other->bDeleteExistingMorphTargetCurves;
	bDeleteExistingNonCurveCustomAttributes = Other->bDeleteExistingNonCurveCustomAttributes;
	bDoNotImportCurveWithZero = Other->bDoNotImportCurveWithZero;
	bImportBoneTracks = Other->bImportBoneTracks;
	bImportCustomAttribute = Other->bImportCustomAttribute;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimationExport.cpp:579

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportAnimTrack

Source code excerpt:

	int32 LocalStartFrame = AnimTrackAdapter.GetLocalStartFrame();
	int32 StartFrame = AnimTrackAdapter.GetStartFrame();
	int32 AnimationLength = AnimTrackAdapter.GetLength();
	double FrameRate = AnimTrackAdapter.GetFrameRate();

	TArray<USkeletalMeshComponent*> SkeletalMeshComponents;
	Actor->GetComponents(SkeletalMeshComponents);

	const double TickRate = 1.0/FrameRate;

	FScopedSlowTask SlowTask(AnimationLength + 1, NSLOCTEXT("UnrealEd", "ExportAnimationProgress", "Exporting Animation"));
	SlowTask.MakeDialog(true);

	for (int32 FrameCount = 0; FrameCount <= AnimationLength; ++FrameCount)
	{
		SlowTask.EnterProgressFrame();
		
		int32 LocalFrame = LocalStartFrame + FrameCount;
		double SampleTime = (StartFrame + FrameCount) / FrameRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimationExport.cpp:645

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportAnimTrack

Source code excerpt:

		{
			NextUpdateTime = UpdateFrequency;
			GWarn->StatusUpdate( FMath::RoundToInt( SampleTime ), AnimationLength, NSLOCTEXT("FbxExporter", "ExportingToFbxStatus", "Exporting to FBX") );
		}

		TArray<FTransform> LocalBoneTransforms = InSkeletalMeshComponent->GetBoneSpaceTransforms();

		if (LocalBoneTransforms.Num() == 0)
		{

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxFactory.cpp:1265

Scope (from outer to inner):

file
function     bool UFbxImportUI::CanEditChange

Source code excerpt:

		if(PropName == TEXT("FrameImportRange"))
		{
			bIsMutable = AnimSequenceImportData->AnimationLength == FBXALIT_SetRange && bImportAnimations;
		}
		else if(PropName == TEXT("bImportCustomAttribute") || PropName == TEXT("AnimationLength") || PropName == TEXT("CustomSampleRate") || PropName == TEXT("bUseDefaultSampleRate"))
		{
			bIsMutable = bImportAnimations;
		}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainExport.cpp:2378

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportTransformChannelsToFbxCurve

Source code excerpt:

	int32 LocalStartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(PlaybackRange)), TickResolution, DisplayRate).RoundToFrame().Value;
	int32 StartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(PlaybackRange) * RootToLocalTransform.InverseNoLooping()), TickResolution, DisplayRate).RoundToFrame().Value;
	int32 AnimationLength = FFrameRate::TransformTime(FFrameTime(FFrameNumber(UE::MovieScene::DiscreteSize(PlaybackRange))), TickResolution, DisplayRate).RoundToFrame().Value;

	for (int32 FrameCount = 0; FrameCount <= AnimationLength; ++FrameCount)
	{
		int32 LocalFrame = LocalStartFrame + FrameCount;

		FFrameTime LocalTime = FFrameRate::TransformTime(FFrameTime(LocalFrame), DisplayRate, TickResolution);

		FVector3f Vec = FVector3f::ZeroVector;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainExport.cpp:2783

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportBezierChannelToFbxCurveBaked

Source code excerpt:

	int32 LocalStartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(PlaybackRange)), TickResolution, DisplayRate).RoundToFrame().Value;
	int32 StartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(PlaybackRange) * RootToLocalTransform.InverseNoLooping()), TickResolution, DisplayRate).RoundToFrame().Value;
	int32 AnimationLength = FFrameRate::TransformTime(FFrameTime(FFrameNumber(UE::MovieScene::DiscreteSize(PlaybackRange))), TickResolution, DisplayRate).RoundToFrame().Value;

	for (int32 FrameCount = 0; FrameCount <= AnimationLength; ++FrameCount)
	{
		int32 LocalFrame = LocalStartFrame + FrameCount;

		FFrameTime LocalTime = FFrameRate::TransformTime(FFrameTime(LocalFrame), DisplayRate, TickResolution);

		float Value;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainExport.cpp:3059

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportLevelSequence3DTransformTrack

Source code excerpt:

		int32 LocalStartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(InPlaybackRange)), TickResolution, DisplayRate).RoundToFrame().Value;
		int32 StartFrame = FFrameRate::TransformTime(FFrameTime(UE::MovieScene::DiscreteInclusiveLower(InPlaybackRange) * RootToLocalTransform.InverseNoLooping()), TickResolution, DisplayRate).RoundToFrame().Value;
		int32 AnimationLength = FFrameRate::TransformTime(FFrameTime(FFrameNumber(UE::MovieScene::DiscreteSize(InPlaybackRange))), TickResolution, DisplayRate).RoundToFrame().Value;

		for (int32 FrameCount = 0; FrameCount <= AnimationLength; ++FrameCount)
		{
			int32 LocalFrame = LocalStartFrame + FrameCount;

			FFrameTime LocalTime = FFrameRate::TransformTime(FFrameTime(LocalFrame), DisplayRate, TickResolution);

			FVector3f Trans = FVector3f::ZeroVector;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainExport.cpp:3247

Scope (from outer to inner):

file
namespace    UnFbx
function     void FFbxExporter::ExportLevelSequenceBaked3DTransformTrack

Source code excerpt:

	TArray<FTransform> RelativeTransforms;
	int32 LocalStartFrame = FFrameRate::TransformTime(FFrameTime(DiscreteInclusiveLower(InPlaybackRange)), TickResolution, DisplayRate).RoundToFrame().Value;
	int32 AnimationLength = FFrameRate::TransformTime(FFrameTime(FFrameNumber(DiscreteSize(InPlaybackRange))), TickResolution, DisplayRate).RoundToFrame().Value + 1; // Add one so that we export a key for the end frame

	const double SampleRate = 1.0/DisplayRate.AsDecimal();

	for (int32 FrameNumber = LocalStartFrame; FrameNumber < LocalStartFrame + AnimationLength; ++FrameNumber)
	{
		const FFrameTime FrameTime = FFrameRate::TransformTime(FrameNumber, DisplayRate, TickResolution);

		// This will call UpdateSkelPose on the skeletal mesh component to move bones based on animations in the matinee group
		AnimTrackAdapter.UpdateAnimation(FrameNumber);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:499

Scope (from outer to inner):

file
namespace    UnFbx
function     void ApplyImportUIToImportOptions

Source code excerpt:

	{
		
		InOutImportOptions.AnimationLengthImportType	= ImportUI->AnimSequenceImportData->AnimationLength;
		InOutImportOptions.AnimationRange.X				= ImportUI->AnimSequenceImportData->FrameImportRange.Min;
		InOutImportOptions.AnimationRange.Y				= ImportUI->AnimSequenceImportData->FrameImportRange.Max;
		// only re-sample if they don't want to use default sample rate
		InOutImportOptions.bResample					= !ImportUI->AnimSequenceImportData->bUseDefaultSampleRate;
		InOutImportOptions.ResampleRate					= ImportUI->AnimSequenceImportData->CustomSampleRate;
		InOutImportOptions.bSnapToClosestFrameBoundary	= ImportUI->AnimSequenceImportData->bSnapToClosestFrameBoundary;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxOptionWindow.cpp:216

Scope (from outer to inner):

file
function     bool SFbxOptionWindow::CanImport

Source code excerpt:

	}

	if (ImportUI->AnimSequenceImportData->AnimationLength == FBXALIT_SetRange)
	{
		if (ImportUI->AnimSequenceImportData->FrameImportRange.Min > ImportUI->AnimSequenceImportData->FrameImportRange.Max)
		{
			return false;
		}
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:25

Scope (from outer to inner):

file
function     UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh

Source code excerpt:

	, MorphThresholdPosition(THRESH_POINTS_ARE_NEAR)
	, bImportAnimations(true)
	, AnimationLength(EFBXAnimationLengthImportType::FBXALIT_AnimatedKey)
	, FrameImportRange(0, 0)
	, bUseDefaultSampleRate(false)
	, CustomSampleRate(0)
	, bImportCustomAttribute(true)
	, bDeleteExistingCustomAttributeCurves(false)
	, bDeleteExistingNonCurveCustomAttributes(false)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:63

Scope (from outer to inner):

file
function     void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData

Source code excerpt:


	AnimSequenceImportData->bImportMeshesInBoneHierarchy = bImportMeshesInBoneHierarchy;
	AnimSequenceImportData->AnimationLength = AnimationLength;
	AnimSequenceImportData->bDeleteExistingMorphTargetCurves = bDeleteExistingMorphTargetCurves;
	AnimSequenceImportData->bImportCustomAttribute = bImportCustomAttribute;
	AnimSequenceImportData->bDeleteExistingCustomAttributeCurves = bDeleteExistingCustomAttributeCurves;
	AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes = bDeleteExistingNonCurveCustomAttributes;
	AnimSequenceImportData->bPreserveLocalTransform = bPreserveLocalTransform;
	AnimSequenceImportData->bUseDefaultSampleRate = bUseDefaultSampleRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1507

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions

Source code excerpt:


	ImportSettings->bImportAnimations = SkeletalMeshOptions->bImportAnimations;
	ImportSettings->AnimationLengthImportType = SkeletalMeshOptions->AnimationLength;
	ImportSettings->bDeleteExistingMorphTargetCurves = SkeletalMeshOptions->bDeleteExistingMorphTargetCurves;
	ImportSettings->bImportCustomAttribute = SkeletalMeshOptions->bImportCustomAttribute;
	ImportSettings->bDeleteExistingCustomAttributeCurves = SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves;
	ImportSettings->bDeleteExistingNonCurveCustomAttributes = SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes;	
	ImportSettings->bPreserveLocalTransform = SkeletalMeshOptions->bPreserveLocalTransform;
	ImportSettings->bResample = !SkeletalMeshOptions->bUseDefaultSampleRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1536

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions

Source code excerpt:


	SkeletalMeshOptions->bImportAnimations = ImportSettings->bImportAnimations;
	SkeletalMeshOptions->AnimationLength = ImportSettings->AnimationLengthImportType;
	SkeletalMeshOptions->bDeleteExistingMorphTargetCurves = ImportSettings->bDeleteExistingMorphTargetCurves;
	SkeletalMeshOptions->bImportCustomAttribute = ImportSettings->bImportCustomAttribute;
	SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves = ImportSettings->bDeleteExistingCustomAttributeCurves;
	SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes = ImportSettings->bDeleteExistingNonCurveCustomAttributes;	
	SkeletalMeshOptions->bPreserveLocalTransform = ImportSettings->bPreserveLocalTransform;
	SkeletalMeshOptions->bUseDefaultSampleRate = !ImportSettings->bResample;

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneTracks/Private/Evaluation/MovieSceneBaseCacheTemplate.cpp:10

Scope (from outer to inner):

file
function     float FMovieSceneBaseCacheSectionTemplateParameters::MapTimeToAnimation

Source code excerpt:

{
	const float SequenceLength = ComponentDuration;
	const FFrameTime AnimationLength = SequenceLength * InFrameRate;
	const int32 LengthInFrames = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
	
	//we only play end if we are not looping, and assuming we are looping if Length is greater than default length;
	const bool bLooping = (SectionEndTime.Value - SectionStartTime.Value + BaseParams.StartFrameOffset + BaseParams.EndFrameOffset) > LengthInFrames;

	InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime - 1));

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneTracks/Private/Sections/MovieSceneBaseCacheSection.cpp:35

Scope (from outer to inner):

file
function     TOptional<TRange<FFrameNumber> > UMovieSceneBaseCacheSection::GetAutoSizeRange

Source code excerpt:

	{
		const FFrameRate FrameRate = GetTypedOuter<UMovieScene>()->GetTickResolution();
		const FFrameTime AnimationLength = ParamsPtr->GetSequenceLength() * FrameRate;
		const int32 IFrameNumber = AnimationLength.FrameNumber.Value + static_cast<int32>(AnimationLength.GetSubFrame() + 0.5f);

		return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + IFrameNumber + 1);
	}
	return TRange<FFrameNumber>(0, 1);
}

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneTracks/Private/Sections/MovieSceneSkeletalAnimationSection.cpp:58

Scope (from outer to inner):

file
function     double FMovieSceneSkeletalAnimationParams::MapTimeToAnimation

Source code excerpt:

	if (Animation)
	{
		const FFrameTime AnimationLength = GetSequenceLength() * InFrameRate;
		const int32 LengthInFrames = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;

		// we only play end if we are not looping, and assuming we are looping if Length is greater than default length;
		const bool bLooping = (InSectionEndTime.Value - InSectionStartTime.Value + StartFrameOffset + EndFrameOffset) > LengthInFrames;

		// Make sure InPosition FrameTime doesn't underflow InSectionStartTime or overflow InSectionEndTime
		InPosition = FMath::Clamp(InPosition, FFrameTime(InSectionStartTime), FFrameTime(InSectionEndTime - 1));

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneTracks/Private/Sections/MovieSceneSkeletalAnimationSection.cpp:278

Scope (from outer to inner):

file
function     TOptional<TRange<FFrameNumber> > UMovieSceneSkeletalAnimationSection::GetAutoSizeRange

Source code excerpt:


	const FFrameTime UnscaledAnimationLength = FMath::Max(Params.GetSequenceLength() * FrameRate - Params.FirstLoopStartFrameOffset - Params.StartFrameOffset - Params.EndFrameOffset, FFrameTime(1));
	const FFrameTime AnimationLength = UnscaledAnimationLength / AnimPlayRate;
	const int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f);

	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + IFrameNumber + 1);
}


void UMovieSceneSkeletalAnimationSection::TrimSection(FQualifiedFrameTime TrimTime, bool bTrimLeft, bool bDeleteKeys)

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneTracks/Private/Tracks/MovieSceneSkeletalAnimationTrack.cpp:56

Scope (from outer to inner):

file
function     UMovieSceneSection* UMovieSceneSkeletalAnimationTrack::AddNewAnimationOnRow

Source code excerpt:

	UMovieSceneSkeletalAnimationSection* NewSection = Cast<UMovieSceneSkeletalAnimationSection>(CreateNewSection());
	{
		FFrameTime AnimationLength = AnimSequence->GetPlayLength() * GetTypedOuter<UMovieScene>()->GetTickResolution();
		int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1;
		NewSection->InitialPlacementOnRow(AnimationSections, KeyTime, IFrameNumber, RowIndex);
		NewSection->Params.Animation = AnimSequence;

#if WITH_EDITORONLY_DATA
		FQualifiedFrameTime SourceStartFrameTime;
		if (UAnimationBlueprintLibrary::EvaluateRootBoneTimecodeAttributesAtTime(NewSection->Params.Animation, 0.0f, SourceStartFrameTime))