LoopMode
LoopMode
#Overview
name: LoopMode
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 15
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of LoopMode is to control the playback loop behavior in the Unreal Engine’s Sequencer system. This variable is used to determine how sequences should play back, whether they should loop continuously, loop within a specific range, or not loop at all.
LoopMode is primarily used in the Sequencer subsystem, which is part of Unreal Engine’s cinematics and animation tools. It’s also utilized in related plugins such as ConcertSync, SequencerPlaylists, and Takes.
The value of this variable is typically set through the Sequencer settings. It can be modified programmatically using the SetLoopMode() function of the USequencerSettings class.
LoopMode interacts with other Sequencer-related variables and functions, such as the playback range, selection range, and playhead position.
Developers should be aware that changing the LoopMode can affect the playback behavior of sequences, which may impact gameplay, cinematics, or other time-based events in the game. It’s important to consider the implications of changing this setting, especially in multiplayer or networked environments.
Best practices when using this variable include:
- Use the provided enums (ESequencerLoopMode) to set the LoopMode rather than raw values.
- Consider the current state of the Sequencer (e.g., selection range) when changing the LoopMode.
- Be mindful of performance implications when using loop modes, especially with complex sequences.
- Use the appropriate getter and setter methods (GetLoopMode() and SetLoopMode()) to interact with this variable.
- Listen to the OnLoopStateChangedEvent broadcast if you need to react to loop mode changes in other parts of your code.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:889, section: [NiagaraSequenceEditor SequencerSettings]
- INI Section:
NiagaraSequenceEditor SequencerSettings
- Raw value:
SLM_Loop
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Developer/Concert/ConcertSync/ConcertSyncClient/Source/ConcertSyncClient/Private/ConcertClientSequencerManager.cpp:427
Scope (from outer to inner):
file
namespace UE::Private::ConcertClientSequencerManager
function bool IsLoopingEnabled
Source code excerpt:
if (USequencerSettings* Settings = InSequencer->GetSequencerSettings())
{
ESequencerLoopMode LoopMode = Settings->GetLoopMode();
if (LoopMode == SLM_Loop || LoopMode == SLM_LoopSelectionRange)
{
return true;
}
}
return false;
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1160
Scope (from outer to inner):
file
function void SSequencerPlaylistItemWidget::Construct
Source code excerpt:
RowData = InRowData;
LoopMode = InRowData->WeakItem->NumLoops == 0 ? ELoopMode::None : ELoopMode::Finite;
PlayMode = InArgs._PlayMode;
IsPlaying = InArgs._IsPlaying;
IsPaused = InArgs._IsPaused;
PlayClickedDelegate = InArgs._OnPlayClicked;
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1522
Scope (from outer to inner):
file
lambda-function
lambda-function
Source code excerpt:
FExecuteAction::CreateLambda([this]() { SetLoopMode(ELoopMode::None); }),
FCanExecuteAction(),
FGetActionCheckState::CreateLambda([this]() { return LoopMode == ELoopMode::None ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; })
),
NAME_None,
EUserInterfaceActionType::Check
);
MenuBuilder.AddMenuEntry(
// U+1D62F = "Mathematical Sans-Serif Italic Small N"
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1535
Scope (from outer to inner):
file
lambda-function
lambda-function
Source code excerpt:
FExecuteAction::CreateLambda([this]() { SetLoopMode(ELoopMode::Finite); }),
FCanExecuteAction(),
FGetActionCheckState::CreateLambda([this]() { return LoopMode == ELoopMode::Finite ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; })
),
NAME_None,
EUserInterfaceActionType::Check
);
return MenuBuilder.MakeWidget();
})
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1553
Scope (from outer to inner):
file
function TSharedRef<SWidget> SSequencerPlaylistItemWidget::GenerateWidgetForColumn
lambda-function
Source code excerpt:
.ColorAndOpacity(FSlateColor::UseForeground())
.Image_Lambda([this]() -> const FSlateBrush* {
switch (LoopMode) {
case ELoopMode::None: return FSequencerPlaylistsStyle::Get().GetBrush("SequencerPlaylists.Loop.Disabled");
case ELoopMode::Finite: return FSequencerPlaylistsStyle::Get().GetBrush("SequencerPlaylists.Loop.Finite");
default: checkNoEntry(); return nullptr;
}
})
]
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1579
Scope (from outer to inner):
file
lambda-function
Source code excerpt:
.ToolTipText(LOCTEXT("LoopCountTooltip", "Number of times to loop before stopping. A value of 1 will result in a sequence playing twice before stopping."))
.Value(TAttribute<TOptional<int32>>::CreateLambda([WeakItem]() { return WeakItem.IsValid() ? WeakItem->NumLoops : TOptional<int32>(); }))
.Visibility_Lambda([this]() { return LoopMode == ELoopMode::Finite ? EVisibility::Visible : EVisibility::Hidden; })
.OnValueChanged_Lambda([WeakItem](int32 NewValue) {
if (WeakItem.IsValid())
{
WeakItem->NumLoops = NewValue;
}
})
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.cpp:1700
Scope (from outer to inner):
file
function void SSequencerPlaylistItemWidget::SetLoopMode
Source code excerpt:
void SSequencerPlaylistItemWidget::SetLoopMode(ELoopMode InLoopMode)
{
if (LoopMode == InLoopMode)
{
return;
}
LoopMode = InLoopMode;
if (InLoopMode == ELoopMode::None)
{
USequencerPlaylistItem* Item = RowData->WeakItem.Get();
if (ensure(Item))
{
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/SequencerPlaylists/Source/SequencerPlaylists/Private/SequencerPlaylistsWidgets.h:226
Scope (from outer to inner):
file
class class SSequencerPlaylistItemWidget : public SMultiColumnTableRow<TSharedPtr<FSequencerPlaylistRowData>>
Source code excerpt:
TSharedPtr<SMenuAnchor> DetailsAnchor;
ELoopMode LoopMode;
TAttribute<bool> PlayMode;
TAttribute<bool> IsPlaying;
TAttribute<bool> IsPaused;
FOnClickedSequencerPlaylistItem PlayClickedDelegate;
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/Takes/Source/CacheTrackRecorder/Private/Recorder/CacheTrackRecorder.cpp:472
Scope (from outer to inner):
file
function bool UCacheTrackRecorder::Initialize
Source code excerpt:
Sequencer->SetPlaybackSpeed(1);
}
ESequencerLoopMode LoopMode = Sequencer->GetSequencerSettings()->GetLoopMode();
if (LoopMode != SLM_NoLoop)
{
Sequencer->GetSequencerSettings()->SetLoopMode(SLM_NoLoop);
OnStopCleanup.Add([LoopMode, this] { WeakSequencer.Pin()->GetSequencerSettings()->SetLoopMode(LoopMode); });
}
}
return true;
}
#Loc: <Workspace>/Engine/Source/Editor/Sequencer/Private/Sequencer.cpp:4783
Scope (from outer to inner):
file
function FReply FSequencer::OnCycleLoopMode
Source code excerpt:
FReply FSequencer::OnCycleLoopMode()
{
ESequencerLoopMode LoopMode = Settings->GetLoopMode();
if (LoopMode == ESequencerLoopMode::SLM_NoLoop)
{
Settings->SetLoopMode(ESequencerLoopMode::SLM_Loop);
}
else if (LoopMode == ESequencerLoopMode::SLM_Loop && !GetSelectionRange().IsEmpty())
{
Settings->SetLoopMode(ESequencerLoopMode::SLM_LoopSelectionRange);
}
else if (LoopMode == ESequencerLoopMode::SLM_LoopSelectionRange || GetSelectionRange().IsEmpty())
{
Settings->SetLoopMode(ESequencerLoopMode::SLM_NoLoop);
}
return FReply::Handled();
}
#Loc: <Workspace>/Engine/Source/Editor/Sequencer/Private/SequencerSettings.cpp:37
Scope (from outer to inner):
file
function USequencerSettings::USequencerSettings
Source code excerpt:
bSynchronizeCurveEditorSelection = true;
bIsolateCurveEditorToSelection = true;
LoopMode = ESequencerLoopMode::SLM_NoLoop;
bSnapKeysAndSectionsToPlayRange = false;
bResetPlayheadWhenNavigating = false;
bKeepCursorInPlayRangeWhileScrubbing = false;
bKeepPlayRangeInSectionBounds = true;
bCompileDirectorOnEvaluate = true;
bLeftMouseDragDoesMarquee = false;
#Loc: <Workspace>/Engine/Source/Editor/Sequencer/Private/SequencerSettings.cpp:452
Scope (from outer to inner):
file
function ESequencerLoopMode USequencerSettings::GetLoopMode
Source code excerpt:
ESequencerLoopMode USequencerSettings::GetLoopMode() const
{
return LoopMode;
}
void USequencerSettings::SetLoopMode(ESequencerLoopMode InLoopMode)
{
if (LoopMode != InLoopMode)
{
LoopMode = InLoopMode;
OnLoopStateChangedEvent.Broadcast();
SaveConfig();
}
}
bool USequencerSettings::ShouldResetPlayheadWhenNavigating() const
#Loc: <Workspace>/Engine/Source/Editor/Sequencer/Public/SequencerSettings.h:600
Scope (from outer to inner):
file
class class USequencerSettings : public UObject
Source code excerpt:
/** The loop mode of the playback in timeline. */
UPROPERTY( config )
TEnumAsByte<ESequencerLoopMode> LoopMode;
/** Enable or disable resetting the playhead when navigating in and out of subsequences. */
UPROPERTY(config, EditAnywhere, Category = Timeline, meta = (DisplayName = "Reset Playhead When Navigating"))
bool bResetPlayheadWhenNavigating;
/** Enable or disable keeping the playhead in the current playback range while scrubbing. */
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/VREditorActions.cpp:383
Scope (from outer to inner):
file
function void FVREditorActionCallbacks::ToggleLooping
Source code excerpt:
if (CurrentSequencer != nullptr)
{
ESequencerLoopMode LoopMode = CurrentSequencer->GetSequencerSettings()->GetLoopMode();
if (LoopMode == ESequencerLoopMode::SLM_NoLoop)
{
CurrentSequencer->GetSequencerSettings()->SetLoopMode(ESequencerLoopMode::SLM_Loop);
}
else if (LoopMode == ESequencerLoopMode::SLM_Loop && !CurrentSequencer->GetSelectionRange().IsEmpty())
{
CurrentSequencer->GetSequencerSettings()->SetLoopMode(ESequencerLoopMode::SLM_LoopSelectionRange);
}
else if (LoopMode == ESequencerLoopMode::SLM_LoopSelectionRange || CurrentSequencer->GetSelectionRange().IsEmpty())
{
CurrentSequencer->GetSequencerSettings()->SetLoopMode(ESequencerLoopMode::SLM_NoLoop);
}
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessWeightedSampleSum.cpp:204
Scope (from outer to inner):
file
function uint32 GetStaticSampleCount
Source code excerpt:
uint32 GetStaticSampleCount(uint32 RequiredSampleCount)
{
const int32 LoopMode = CVarLoopMode.GetValueOnRenderThread();
const bool bForceStaticLoop = LoopMode == 0;
const bool bForceDynamicLoop = LoopMode == 2;
if (!bForceDynamicLoop && (bForceStaticLoop || RequiredSampleCount <= MAX_FILTER_COMPILE_TIME_SAMPLES))
{
return RequiredSampleCount;
}
else