MaxSubsteps

MaxSubsteps

#Overview

name: MaxSubsteps

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

#Summary

#Usage in the C++ source code

The purpose of MaxSubsteps is to control the maximum number of physics simulation substeps that can be performed within a single frame. This variable is primarily used in the physics simulation system of Unreal Engine 5.

The MaxSubsteps variable is utilized by the following Unreal Engine subsystems and modules:

  1. AnimGraphRuntime: Used in the AnimDynamics node for skeletal animation physics simulation.
  2. Engine: Used in the core physics simulation system, particularly in PhysicsSettings and PhysScene setup.

The value of MaxSubsteps is typically set in the UPhysicsSettings class, which is part of the Engine module. It is initialized with a default value of 6 in the UPhysicsSettings constructor.

MaxSubsteps interacts with other physics-related variables, such as:

Developers should be aware of the following when using MaxSubsteps:

  1. Increasing MaxSubsteps can improve physics simulation accuracy but at the cost of performance.
  2. The actual number of substeps used in a frame is dynamically calculated based on the frame’s delta time and the MaxSubstepDeltaTime.
  3. MaxSubsteps is clamped between 1 and 16 in the UPhysicsSettings class.

Best practices for using MaxSubsteps include:

  1. Balance between simulation accuracy and performance by adjusting MaxSubsteps along with MaxSubstepDeltaTime.
  2. Monitor performance metrics to ensure that increasing MaxSubsteps doesn’t negatively impact frame rate.
  3. Consider the specific requirements of your game or application when adjusting this value, as different scenarios may benefit from different settings.
  4. Use the UPhysicsSettings class to modify this value globally, rather than changing it in individual components or functions.

#Setting Variables

#References In INI files

Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:343, section: [/Script/Engine.PhysicsSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Private/BoneControllers/AnimNode_AnimDynamics.cpp:384

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::EvaluateSkeletalControl_AnyThread

Source code excerpt:

				// Calculate number of substeps we should do.
				int32 NumIters = FMath::TruncToInt((NextTimeStep + (TimeDebt * CurrentTimeDilation)) / FixedTimeStep);
				NumIters = FMath::Clamp(NumIters, 0, MaxSubsteps);

				SET_DWORD_STAT(STAT_AnimDynamicsSubSteps, NumIters);

				// Store the remaining time as debt for later frames
				TimeDebt = (NextTimeStep + TimeDebt) - (NumIters * FixedTimeStep);
				TimeDebt = FMath::Clamp(TimeDebt, 0.0f, MaxTimeDebt);

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Private/BoneControllers/AnimNode_AnimDynamics.cpp:814

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::InitPhysics

Source code excerpt:

			MaxPhysicsDeltaTime = Settings->MaxPhysicsDeltaTime;
			MaxSubstepDeltaTime = Settings->MaxSubstepDeltaTime;
			MaxSubsteps = Settings->MaxSubsteps;
		}
		else
		{
			AnimPhysicsMinDeltaTime = 0.f;
			MaxPhysicsDeltaTime = (1.0f / 30.0f);
			MaxSubstepDeltaTime = (1.0f / 60.0f);
			MaxSubsteps = 4;
		}

		SimSpaceGravityDirection = TransformWorldVectorToSimSpace(Output, FVector(0.0f, 0.0f, -1.0f));
	}
	break;

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Public/BoneControllers/AnimNode_AnimDynamics.h:548

Scope: file

Source code excerpt:

	float MaxPhysicsDeltaTime;
	float MaxSubstepDeltaTime;
	int32 MaxSubsteps;
	//////////////////////////////////////////////////////////////////////////

	// Active body list
	TArray<FAnimPhysLinkedBody> Bodies;

	// Pointers to bodies that need to be reset to their bound bone.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/PhysicsEngine/PhysicsSettings.h:225

Scope (from outer to inner):

file
class        class UPhysicsSettings : public UPhysicsSettingsCore

Source code excerpt:

	/** Max number of substeps for physics simulation. */
	UPROPERTY(config, EditAnywhere, meta = (ClampMin = "1", UIMin = "1", ClampMax = "16", UIMax = "16", editcondition = "bSubstepping"), Category=Framerate)
	int32 MaxSubsteps;

	/** Physics delta time smoothing factor for sync scene. */
	UPROPERTY(config, EditAnywhere, AdvancedDisplay, meta = (ClampMin = "0.0", UIMin = "0.0", ClampMax = "1.0", UIMax = "1.0"), Category = Framerate)
	float SyncSceneSmoothingFactor;

	/** Physics delta time initial average. */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysLevel.cpp:147

Scope (from outer to inner):

file
function     void UWorld::SetupPhysicsTickFunctions

Source code excerpt:

	static const auto CVar_MaxPhysicsDeltaTime = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("p.MaxPhysicsDeltaTime"));
	PhysScene->SetUpForFrame(&DefaultGravity, DeltaSeconds, UPhysicsSettings::Get()->MinPhysicsDeltaTime, UPhysicsSettings::Get()->MaxPhysicsDeltaTime,
		UPhysicsSettings::Get()->MaxSubstepDeltaTime, UPhysicsSettings::Get()->MaxSubsteps, UPhysicsSettings::Get()->bSubstepping);
}

void UWorld::StartPhysicsSim()
{
	FPhysScene* PhysScene = GetPhysicsScene();
	if (PhysScene == NULL)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysSubstepTasks.cpp:215

Scope (from outer to inner):

file
function     float FPhysSubstepTask::UpdateTime

Source code excerpt:

	UPhysicsSettings * PhysSetting = UPhysicsSettings::Get();
	FrameRate = PhysSetting->MaxSubstepDeltaTime;
	MaxSubSteps = PhysSetting->MaxSubsteps;
	
	float FrameRateInv = 1.f / FrameRate;

	//Figure out how big dt to make for desired framerate
	DeltaSeconds = FMath::Min(UseDelta, MaxSubSteps * FrameRate);
	NumSubsteps = FMath::CeilToInt(DeltaSeconds * FrameRateInv);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsSettings.cpp:24

Scope (from outer to inner):

file
function     UPhysicsSettings::UPhysicsSettings

Source code excerpt:

	, AsyncFixedTimeStepSize(1.f / 30.f)
	, MaxSubstepDeltaTime(1.f / 60.f)
	, MaxSubsteps(6)
	, SyncSceneSmoothingFactor(0.0f)
	, InitialAverageFrameRate(1.f / 60.f)
	, PhysXTreeRebuildRate(10)
	, MinDeltaVelocityForHitEvents(0.f)
{
}