MaxPhysicsDeltaTime

MaxPhysicsDeltaTime

#Overview

name: MaxPhysicsDeltaTime

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 MaxPhysicsDeltaTime is to set an upper limit on the time step used for physics simulation in Unreal Engine 5. This variable is part of the physics system and is used to ensure stable and consistent physics simulations across varying frame rates.

MaxPhysicsDeltaTime is primarily used by the physics engine and related systems, such as cloth simulation, animation dynamics, and spring arm components. It is referenced in various modules and plugins, including:

  1. ChaosClothAsset
  2. LearningAgentsTraining
  3. AnimGraphRuntime
  4. ClothingSystemRuntimeCommon
  5. Engine (PhysicsSettings, SpringArmComponent, PhysLevel)

The value of this variable is typically set in the UPhysicsSettings class, which is part of the Engine module. It can be modified through project settings or programmatically.

MaxPhysicsDeltaTime interacts with other physics-related variables such as MinPhysicsDeltaTime, MaxSubstepDeltaTime, and MaxSubsteps. These variables work together to control the physics simulation behavior and performance.

Developers should be aware that:

  1. Changing MaxPhysicsDeltaTime can affect the stability and accuracy of physics simulations.
  2. Setting it too high may result in less accurate simulations, while setting it too low may impact performance.
  3. This variable is used to clamp the physics time step, which helps prevent issues with extremely large time steps that can occur during frame rate drops or when the game is paused.

Best practices when using this variable include:

  1. Keep the value relatively low (e.g., 1/30 seconds) to ensure stable simulations.
  2. Consider the target frame rate of your game when setting this value.
  3. Use in conjunction with substepping for more accurate simulations at lower frame rates.
  4. Test thoroughly after modifying this value to ensure it doesn’t negatively impact gameplay or performance.
  5. Be cautious when changing this value during runtime, as it may affect the consistency of physics simulations across different parts of the game.

#Setting Variables

#References In INI files

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

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/ChaosClothAsset/Source/ChaosClothAssetEngine/Private/ChaosClothAsset/ClothSimulationContext.h:39

Scope (from outer to inner):

file
namespace    UE::Chaos::ClothAsset

Source code excerpt:

		bool bReset = false;

		/** Velocity scale to compensate for time differences when the MaxPhysicsDeltaTime kicks in. */
		float VelocityScale;

		/** Gravity extracted from the world. */
		FVector WorldGravity;

		/** Wind velocity at the component location. */

#Loc: <Workspace>/Engine/Plugins/ChaosClothAsset/Source/ChaosClothAssetEngine/Private/ChaosClothAsset/ClothSimulationProxy.cpp:93

Scope (from outer to inner):

file
namespace    UE::Chaos::ClothAsset
function     FClothSimulationProxy::FClothSimulationProxy

Source code excerpt:

		, Solver(nullptr)
		, Visualization(nullptr)
		, MaxDeltaTime(UPhysicsSettings::Get()->MaxPhysicsDeltaTime)
	{
		using namespace ::Chaos;

		check(IsInGameThread());

		// Create solver config simulation thread object first. Need to know which solver type we're creating.

#Loc: <Workspace>/Engine/Plugins/ChaosClothAsset/Source/ChaosClothAssetEngine/Public/ChaosClothAsset/ClothSimulationProxy.h:134

Scope (from outer to inner):

file
namespace    UE::Chaos::ClothAsset
function     class CHAOSCLOTHASSETENGINE_API FClothSimulationProxy { public: explicit FClothSimulationProxy

Source code excerpt:

		mutable bool bHasInvalidReferenceBoneTransforms = false;

		// Cached value of the MaxPhysicsDeltaTime setting for the life of this proxy
		const float MaxDeltaTime;
	};

#if !defined(CHAOS_TRANSFORM_CLOTH_SIMUL_DATA_ISPC_ENABLED_DEFAULT)
#define CHAOS_TRANSFORM_CLOTH_SIMUL_DATA_ISPC_ENABLED_DEFAULT 1
#endif

#Loc: <Workspace>/Engine/Plugins/Experimental/LearningAgents/Source/LearningAgentsTraining/Private/LearningAgentsTrainer.cpp:424

Scope (from outer to inner):

file
function     void ULearningAgentsTrainer::BeginTraining

Source code excerpt:

	if (PhysicsSettings)
	{
		MaxPhysicsStep = PhysicsSettings->MaxPhysicsDeltaTime;
	}

	IConsoleVariable* MaxFPSCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("t.MaxFPS"));
	if (MaxFPSCVar)
	{
		MaxFPS = MaxFPSCVar->GetInt();

#Loc: <Workspace>/Engine/Plugins/Experimental/LearningAgents/Source/LearningAgentsTraining/Private/LearningAgentsTrainer.cpp:457

Scope (from outer to inner):

file
function     void ULearningAgentsTrainer::BeginTraining

Source code excerpt:

		if (TrainerGameSettings.bSetMaxPhysicsStepToFixedTimeStep && PhysicsSettings)
		{
			PhysicsSettings->MaxPhysicsDeltaTime = 1.0f / TrainerGameSettings.FixedTimeStepFrequency;
		}
	}
	else
	{
		UE_LOG(LogLearning, Warning, TEXT("%s: Provided invalid FixedTimeStepFrequency: %0.5f"), *GetName(), TrainerGameSettings.FixedTimeStepFrequency);
	}

#Loc: <Workspace>/Engine/Plugins/Experimental/LearningAgents/Source/LearningAgentsTraining/Private/LearningAgentsTrainer.cpp:619

Scope (from outer to inner):

file
function     void ULearningAgentsTrainer::DoneTraining

Source code excerpt:

		if (PhysicsSettings)
		{
			PhysicsSettings->MaxPhysicsDeltaTime = MaxPhysicsStep;
		}

		IConsoleVariable* MaxFPSCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("t.MaxFPS"));
		if (MaxFPSCVar)
		{
			MaxFPSCVar->Set(MaxFPS);

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

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::EvaluateSkeletalControl_AnyThread

Source code excerpt:

				// at high speeds the simulation will not converge as the delta time is too high, this will
				// help to keep constraints together at a cost of physical accuracy
				FixedTimeStep = FMath::Clamp(FixedTimeStep, 0.0f, MaxPhysicsDeltaTime);

				// 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);

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

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::EvaluateSkeletalControl_AnyThread

Source code excerpt:

			{
				// Do variable frame-time update
				const float MaxDeltaTime = MaxPhysicsDeltaTime;

				NextTimeStep = FMath::Min(NextTimeStep, MaxDeltaTime);

				UpdateLimits(Output);
				FAnimPhys::PhysicsUpdate(NextTimeStep, SimBodies, LinearLimits, AngularLimits, Springs, SimSpaceGravityDirection, OrientedExternalForce, ComponentLinearAcc, NumSolverIterationsPreUpdate, NumSolverIterationsPostUpdate);
			}

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

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::InitPhysics

Source code excerpt:

		{
			AnimPhysicsMinDeltaTime = Settings->AnimPhysicsMinDeltaTime;
			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));
	}

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

Scope: file

Source code excerpt:

	// Cached physics settings. We cache these on initialise to avoid the cost of accessing UPhysicsSettings a lot each frame
	float AnimPhysicsMinDeltaTime;
	float MaxPhysicsDeltaTime;
	float MaxSubstepDeltaTime;
	int32 MaxSubsteps;
	//////////////////////////////////////////////////////////////////////////

	// Active body list
	TArray<FAnimPhysLinkedBody> Bodies;

#Loc: <Workspace>/Engine/Source/Runtime/ClothingSystemRuntimeCommon/Private/ClothingSimulation.cpp:198

Scope (from outer to inner):

file
function     FClothingSimulationCommon::FClothingSimulationCommon

Source code excerpt:

FClothingSimulationCommon::FClothingSimulationCommon()
{
	MaxPhysicsDelta = UPhysicsSettings::Get()->MaxPhysicsDeltaTime;
}

FClothingSimulationCommon::~FClothingSimulationCommon()
{}

void FClothingSimulationCommon::FillContext(USkeletalMeshComponent* InComponent, float InDeltaTime, IClothingSimulationContext* InOutContext)

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

Scope (from outer to inner):

file
class        class UPhysicsSettings : public UPhysicsSettingsCore

Source code excerpt:

	/** Max Physics Delta Time to be clamped. */
	UPROPERTY(config, EditAnywhere, meta=(ClampMin="0.0013", UIMin = "0.0013", ClampMax="1.0", UIMax="1.0"), Category=Framerate)
	float MaxPhysicsDeltaTime;

	/** Whether to substep the physics simulation. This feature is still experimental. Certain functionality might not work correctly*/
	UPROPERTY(config, EditAnywhere, Category = Framerate)
	bool bSubstepping;

	/** Whether to substep the async physics simulation. This feature is still experimental. Certain functionality might not work correctly*/

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameFramework/SpringArmComponent.cpp:98

Scope (from outer to inner):

file
function     void USpringArmComponent::UpdateDesiredArmLocation

Source code excerpt:

	{
		// Use the same max timestep cap as the physics system to avoid camera jitter when the viewtarget simulates less time than the camera
		DeltaTime = FMath::Min(DeltaTime, UPhysicsSettings::Get()->MaxPhysicsDeltaTime);
	}

	// Apply 'lag' to rotation if desired
	if(bDoRotationLag)
	{
		if (bUseCameraLagSubstepping && DeltaTime > CameraLagMaxTimeStep && CameraRotationLagSpeed > 0.f)

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

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();

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

Scope (from outer to inner):

file
function     UPhysicsSettings::UPhysicsSettings

Source code excerpt:

	, bSimulateAnimPhysicsAfterReset(false)
	, MinPhysicsDeltaTime(UE_SMALL_NUMBER)
	, MaxPhysicsDeltaTime(1.f / 30.f)
	, bSubstepping(false)
	, bTickPhysicsAsync(false)
	, AsyncFixedTimeStepSize(1.f / 30.f)
	, MaxSubstepDeltaTime(1.f / 60.f)
	, MaxSubsteps(6)
	, SyncSceneSmoothingFactor(0.0f)