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:
- Animation system
- Sequencer
- FBX import/export
- Geometry Cache
- Niagara
- Control Rig
- 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:
- Always calculate it based on the actual animation data and the project’s frame rate to ensure accuracy.
- When modifying animations or creating custom animation systems, make sure to update AnimationLength accordingly.
- Be mindful of how AnimationLength interacts with looping animations and adjust your logic accordingly.
- When working with the FBX import/export system, pay attention to how AnimationLength is set and used to ensure proper animation data transfer.
- 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]
- INI Section:
/Script/UnrealEd.FbxAnimSequenceImportData
- Raw value:
FBXALIT_ExportedTime
- Is Array:
False
#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))