bp.UseLegacyAnimInstanceReinstancingBehavior

bp.UseLegacyAnimInstanceReinstancingBehavior

#Overview

name: bp.UseLegacyAnimInstanceReinstancingBehavior

This variable is created as a Console Variable (cvar).

It is referenced in 7 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of bp.UseLegacyAnimInstanceReinstancingBehavior is to control the behavior of animation instance reinstancing in Unreal Engine 5. It determines whether to use the legacy re-instancing behavior for animation instances where the instance is destroyed and re-created.

This setting variable is primarily used in the animation system of Unreal Engine 5. It affects various components related to animation, including the base AnimInstance, ControlRigLayerInstance, and specific animation nodes like CustomProperty, LinkedAnimGraph, and LinkedAnimLayer.

The value of this variable is set through a console variable, which allows it to be changed at runtime. It is defined in the KismetReinstanceUtilities.cpp file and can be accessed through the console or programmatically.

The variable interacts with the HandleObjectsReinstanced functions in various animation-related classes. When set to false (which is the default), it enables a new reinstancing behavior that is more efficient and maintains better continuity in animation states.

Developers must be aware that changing this variable can significantly impact how animation instances are handled during object reinstancing, which typically occurs during hot-reloading or certain types of blueprint compilation. The new behavior (when the variable is false) is generally preferred as it provides better performance and state preservation.

Best practices when using this variable include:

  1. Generally, leave it set to false (default) to use the improved reinstancing behavior.
  2. Only enable the legacy behavior if experiencing specific issues with animation continuity during hot-reloading or blueprint compilation.
  3. Be consistent in its usage across a project to avoid unexpected behavior.
  4. When debugging animation issues related to object reinstancing, consider toggling this variable to isolate potential causes.
  5. Document any project-specific requirements that necessitate using the legacy behavior.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Kismet2/KismetReinstanceUtilities.cpp:58

Scope: file

Source code excerpt:

bool GUseLegacyAnimInstanceReinstancingBehavior = false;
static FAutoConsoleVariableRef CVarUseLegacyAnimInstanceReinstancingBehavior(
	TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"),
	GUseLegacyAnimInstanceReinstancingBehavior,
	TEXT("Use the legacy re-instancing behavior for anim instances where the instance is destroyed and re-created.")
);

namespace UE::ReinstanceUtils
{

#Loc: <Workspace>/Engine/Plugins/Animation/ControlRig/Source/ControlRig/Private/Sequencer/ControlRigLayerInstance.cpp:175

Scope (from outer to inner):

file
function     void UControlRigLayerInstance::HandleObjectsReinstanced

Source code excerpt:

	Super::HandleObjectsReinstanced(OldToNewInstanceMap);

	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		// Forward to control rig nodes
		FControlRigLayerInstanceProxy& Proxy = GetProxyOnGameThread<FControlRigLayerInstanceProxy>();
		for(TSharedPtr<FAnimNode_ControlRig_ExternalSource>& ControlRigNode : Proxy.ControlRigNodes)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp:4204

Scope (from outer to inner):

file
function     void UAnimInstance::HandleObjectsReinstanced

Source code excerpt:

void UAnimInstance::HandleObjectsReinstanced(const TMap<UObject*, UObject*>& OldToNewInstanceMap)
{
	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		bool bThisObjectWasReinstanced = false;

		for(const TPair<UObject*, UObject*>& ObjectPair : OldToNewInstanceMap)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimNode_CustomProperty.cpp:96

Scope (from outer to inner):

file
function     void FAnimNode_CustomProperty::HandleObjectsReinstanced_Impl

Source code excerpt:

void FAnimNode_CustomProperty::HandleObjectsReinstanced_Impl(UObject* InSourceObject, UObject* InTargetObject, const TMap<UObject*, UObject*>& OldToNewInstanceMap)
{
	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		if(InSourceObject)
		{
			InitializeProperties(CastChecked<UAnimInstance>(InSourceObject), GetTargetClass());
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimNode_CustomProperty.cpp:108

Scope (from outer to inner):

file
function     void FAnimNode_CustomProperty::HandleObjectsReinstanced

Source code excerpt:

void FAnimNode_CustomProperty::HandleObjectsReinstanced(const TMap<UObject*, UObject*>& OldToNewInstanceMap)
{
	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		UObject* TargetObject = GetTargetInstance<UObject>();
		UObject* SourceObject = SourceInstance;

		if(TargetObject && SourceObject)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimNode_LinkedAnimGraph.cpp:505

Scope (from outer to inner):

file
function     void FAnimNode_LinkedAnimGraph::HandleObjectsReinstanced_Impl

Source code excerpt:

void FAnimNode_LinkedAnimGraph::HandleObjectsReinstanced_Impl(UObject* InSourceObject, UObject* InTargetObject, const TMap<UObject*, UObject*>& OldToNewInstanceMap)
{
	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		UAnimInstance* SourceAnimInstance = CastChecked<UAnimInstance>(InSourceObject);
		FAnimInstanceProxy& SourceProxy = SourceAnimInstance->GetProxyOnAnyThread<FAnimInstanceProxy>();

		// Call Initialize here to ensure any custom proxies are initialized (as they may have been re-created during

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimNode_LinkedAnimLayer.cpp:214

Scope (from outer to inner):

file
function     void FAnimNode_LinkedAnimLayer::HandleObjectsReinstanced_Impl

Source code excerpt:

void FAnimNode_LinkedAnimLayer::HandleObjectsReinstanced_Impl(UObject* InSourceObject, UObject* InTargetObject, const TMap<UObject*, UObject*>& OldToNewInstanceMap)
{
	static IConsoleVariable* UseLegacyAnimInstanceReinstancingBehavior = IConsoleManager::Get().FindConsoleVariable(TEXT("bp.UseLegacyAnimInstanceReinstancingBehavior"));
	if(UseLegacyAnimInstanceReinstancingBehavior == nullptr || !UseLegacyAnimInstanceReinstancingBehavior->GetBool())
	{
		UAnimInstance* SourceAnimInstance = CastChecked<UAnimInstance>(InSourceObject);
		FAnimInstanceProxy& SourceProxy = SourceAnimInstance->GetProxyOnAnyThread<FAnimInstanceProxy>();

		// Call Initialize here to ensure any custom proxies are initialized (as they may have been re-created during