Widget.UseParallelAnimation
Widget.UseParallelAnimation
#Overview
name: Widget.UseParallelAnimation
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Use multi-threaded evaluation for widget animations.
It is referenced in 10
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of Widget.UseParallelAnimation is to control whether widget animations in Unreal Engine 5 are evaluated using multi-threaded processing. This setting is primarily used for optimizing the performance of the UMG (Unreal Motion Graphics) system, which is responsible for creating and managing user interfaces in Unreal Engine.
This setting variable is mainly relied upon by the UMG module, specifically within the animation subsystem of UMG. It affects the behavior of classes such as UUserWidget, UUMGSequencePlayer, and UUMGSequenceTickManager.
The value of this variable is set through a console variable (CVar) named CVarUserWidgetUseParallelAnimation. By default, it is set to true, enabling multi-threaded evaluation for widget animations.
The associated variable CVarUserWidgetUseParallelAnimation interacts directly with Widget.UseParallelAnimation. They share the same value and are used interchangeably in the code.
Developers must be aware that:
- Enabling this variable (set to true) allows for multi-threaded evaluation of widget animations, which can improve performance, especially in scenarios with many animated widgets.
- Disabling this variable (set to false) will cause animations to be evaluated on the main thread, which might be necessary for certain debugging scenarios or if there are synchronization issues.
- The setting affects various aspects of widget animation, including stopping animations, queueing latent actions, and the overall ticking process of widget animations.
Best practices when using this variable include:
- Generally, leave it enabled (true) for better performance in most cases.
- If experiencing issues with widget animations, particularly related to timing or synchronization, try disabling it temporarily for debugging.
- Be cautious when modifying this setting at runtime, as it can affect the behavior of all widget animations in the game.
- When implementing custom widget animation systems, consider checking this variable to ensure compatibility with the engine’s parallel animation system.
Regarding the associated variable CVarUserWidgetUseParallelAnimation: This is the actual console variable that controls the Widget.UseParallelAnimation setting. It is defined in the UMG module and is used throughout the widget animation system to determine whether parallel animation evaluation should be used. The same considerations and best practices apply to this variable as they do to Widget.UseParallelAnimation.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/UserWidget.cpp:43
Scope: file
Source code excerpt:
TAutoConsoleVariable<bool> CVarUserWidgetUseParallelAnimation(
TEXT("Widget.UseParallelAnimation"),
true,
TEXT("Use multi-threaded evaluation for widget animations."),
ECVF_Default
);
uint32 UUserWidget::bInitializingFromWidgetTree = 0;
#Associated Variable and Callsites
This variable is associated with another variable named CVarUserWidgetUseParallelAnimation
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequencePlayer.cpp:13
Scope: file
Source code excerpt:
#include UE_INLINE_GENERATED_CPP_BY_NAME(UMGSequencePlayer)
extern TAutoConsoleVariable<bool> CVarUserWidgetUseParallelAnimation;
namespace UE::UMG
{
bool GAsyncAnimationControlFlow = true;
FAutoConsoleVariableRef CVarAsyncAnimationControlFlow(
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequencePlayer.cpp:380
Scope (from outer to inner):
file
function void UUMGSequencePlayer::Stop
Source code excerpt:
UMovieSceneSequence* MovieSceneSequence = RootTemplateInstance.GetSequence(MovieSceneSequenceID::Root);
const bool bIsRunningWithTickManager = CVarUserWidgetUseParallelAnimation.GetValueOnGameThread();
const bool bIsSequenceBlocking = EnumHasAnyFlags(MovieSceneSequence->GetFlags(), EMovieSceneSequenceFlags::BlockingEvaluation);
const bool bIsAsync = bIsRunningWithTickManager && !bIsSequenceBlocking && UE::UMG::GAsyncAnimationControlFlow == true;
UUserWidget* Widget = UserWidget.Get();
UUMGSequenceTickManager* TickManager = Widget ? ToRawPtr(Widget->AnimationTickManager) : nullptr;
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequencePlayer.cpp:514
Scope (from outer to inner):
file
function void UUMGSequencePlayer::QueueLatentAction
Source code excerpt:
void UUMGSequencePlayer::QueueLatentAction(FMovieSceneSequenceLatentActionDelegate Delegate)
{
if (CVarUserWidgetUseParallelAnimation.GetValueOnGameThread())
{
UUserWidget* Widget = UserWidget.Get();
UUMGSequenceTickManager* TickManager = Widget ? ToRawPtr(Widget->AnimationTickManager) : nullptr;
if (ensure(TickManager))
{
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequencePlayer.cpp:532
Scope (from outer to inner):
file
function void UUMGSequencePlayer::ApplyLatentActions
Source code excerpt:
void UUMGSequencePlayer::ApplyLatentActions()
{
if (CVarUserWidgetUseParallelAnimation.GetValueOnGameThread())
{
UUserWidget* Widget = UserWidget.Get();
UUMGSequenceTickManager* TickManager = Widget ? ToRawPtr(Widget->AnimationTickManager) : nullptr;
if (TickManager)
{
TickManager->RunLatentActions();
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequencePlayer.cpp:586
Scope (from outer to inner):
file
function void UUMGSequencePlayer::BeginDestroy
Source code excerpt:
// Remove any latent actions added by this player.
if (CVarUserWidgetUseParallelAnimation.GetValueOnGameThread())
{
UUserWidget* Widget = UserWidget.Get();
UUMGSequenceTickManager* TickManager = Widget ? ToRawPtr(Widget->AnimationTickManager) : nullptr;
if (TickManager)
{
TickManager->ClearLatentActions(this);
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequenceTickManager.cpp:40
Scope: file
Source code excerpt:
} // namespace UE::UMG
extern TAutoConsoleVariable<bool> CVarUserWidgetUseParallelAnimation;
UUMGSequenceTickManager::UUMGSequenceTickManager(const FObjectInitializer& Init)
: Super(Init)
, bIsTicking(false)
{
if (!HasAnyFlags(RF_ClassDefaultObject))
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/Animation/UMGSequenceTickManager.cpp:107
Scope (from outer to inner):
file
function void UUMGSequenceTickManager::TickWidgetAnimations
Source code excerpt:
void UUMGSequenceTickManager::TickWidgetAnimations(float DeltaSeconds)
{
if (!CVarUserWidgetUseParallelAnimation.GetValueOnGameThread())
{
return;
}
if (bIsTicking)
{
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/UserWidget.cpp:42
Scope: file
Source code excerpt:
#define LOCTEXT_NAMESPACE "UMG"
TAutoConsoleVariable<bool> CVarUserWidgetUseParallelAnimation(
TEXT("Widget.UseParallelAnimation"),
true,
TEXT("Use multi-threaded evaluation for widget animations."),
ECVF_Default
);
#Loc: <Workspace>/Engine/Source/Runtime/UMG/Private/UserWidget.cpp:1810
Scope (from outer to inner):
file
function void UUserWidget::NativeTick
Source code excerpt:
}
if (!CVarUserWidgetUseParallelAnimation.GetValueOnGameThread())
{
TickActionsAndAnimation(InDeltaTime);
PostTickActionsAndAnimation(InDeltaTime);
}
// else: the TickManager object will tick all animations at once.