AnimPhysicsMinDeltaTime

AnimPhysicsMinDeltaTime

#Overview

name: AnimPhysicsMinDeltaTime

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

#Summary

#Usage in the C++ source code

The purpose of AnimPhysicsMinDeltaTime is to set a minimum threshold for the delta time used in animation physics simulations within Unreal Engine 5. This variable is primarily used in the animation and physics systems to control the minimum time step for physics simulations in animation nodes.

AnimPhysicsMinDeltaTime is relied upon by the following Unreal Engine subsystems and modules:

  1. Animation system, specifically in the AnimDynamics and RigidBody animation nodes
  2. Physics system, particularly in physics-based animations

The value of this variable is set in the UPhysicsSettings class, which is part of the Engine module. It can be configured through the project settings in the Unreal Engine editor.

AnimPhysicsMinDeltaTime interacts with other variables such as:

  1. bSimulateAnimPhysicsAfterReset
  2. MaxPhysicsDeltaTime
  3. MaxSubstepDeltaTime
  4. MaxSubsteps

Developers must be aware of the following when using this variable:

  1. Setting it too low may result in performance issues due to frequent physics updates.
  2. Setting it too high may cause animation physics to appear less smooth or responsive.
  3. It affects the behavior of AnimDynamics and RigidBody animation nodes.

Best practices when using this variable include:

  1. Adjust the value based on the specific needs of your project, considering both performance and visual quality.
  2. Test different values to find the optimal balance between simulation accuracy and performance.
  3. Consider the target frame rate of your project when setting this value.
  4. Use in conjunction with other physics settings to achieve the desired animation behavior.

#Setting Variables

#References In INI files

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

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Experimental/PhysicsControl/Source/PhysicsControl/Private/AnimNode_RigidBodyWithControl.cpp:156

Scope (from outer to inner):

file
function     FAnimNode_RigidBodyWithControl::FAnimNode_RigidBodyWithControl

Source code excerpt:

	, LastEvalTimeSeconds(0.0f)
	, AccumulatedDeltaTime(0.0f)
	, AnimPhysicsMinDeltaTime(0.0f)
	, bSimulateAnimPhysicsAfterReset(false)
	, SkelMeshCompWeakPtr()
	, PhysicsSimulation(nullptr)
	, SolverSettings()
	, SolverIterations()
	, SimulationTask()

#Loc: <Workspace>/Engine/Plugins/Experimental/PhysicsControl/Source/PhysicsControl/Private/AnimNode_RigidBodyWithControl.cpp:683

Scope (from outer to inner):

file
function     void FAnimNode_RigidBodyWithControl::EvaluateSkeletalControl_AnyThread

Source code excerpt:

		const bool bNeedsSimulationTick = 
			((bSimulateAnimPhysicsAfterReset || (ResetSimulatedTeleportType != ETeleportType::ResetPhysics)) && 
				DeltaSeconds > AnimPhysicsMinDeltaTime);
		if (bNeedsSimulationTick)
		{
			// Update the pose data
			{
				SCOPE_CYCLE_COUNTER(STAT_RigidBodyNodeWithControl_PoseUpdate);
				PoseData.Update(

#Loc: <Workspace>/Engine/Plugins/Experimental/PhysicsControl/Source/PhysicsControl/Private/AnimNode_RigidBodyWithControl.cpp:984

Scope (from outer to inner):

file
function     void FAnimNode_RigidBodyWithControl::InitPhysics

Source code excerpt:

	if (UPhysicsSettings* Settings = UPhysicsSettings::Get())
	{
		AnimPhysicsMinDeltaTime = Settings->AnimPhysicsMinDeltaTime;
		bSimulateAnimPhysicsAfterReset = Settings->bSimulateAnimPhysicsAfterReset;
	}
	else
	{
		AnimPhysicsMinDeltaTime = 0.f;
		bSimulateAnimPhysicsAfterReset = false;
	}
	
	bEnabled = PhysicsAssetToUse && SkeletalMeshComp->GetAllowRigidBodyAnimNode() && CVarEnableRigidBodyNodeWithControl.GetValueOnAnyThread() != 0;
	if(bEnabled)
	{

#Loc: <Workspace>/Engine/Plugins/Experimental/PhysicsControl/Source/PhysicsControl/Public/AnimNode_RigidBodyWithControl.h:512

Scope: file

Source code excerpt:


	float AccumulatedDeltaTime;
	float AnimPhysicsMinDeltaTime;
	bool bSimulateAnimPhysicsAfterReset;
	/** This should only be used for removing the delegate during termination. Do NOT use this for any per frame work */
	TWeakObjectPtr<USkeletalMeshComponent> SkelMeshCompWeakPtr;

	ImmediatePhysics::FSimulation* PhysicsSimulation;
	FPhysicsAssetSolverSettings SolverSettings;

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

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::EvaluateSkeletalControl_AnyThread

Source code excerpt:

		}

		if (ShouldDoPhysicsUpdate() && NextTimeStep > AnimPhysicsMinDeltaTime)
		{
			// Calculate gravity direction
			SimSpaceGravityDirection = TransformWorldVectorToSimSpace(Output, FVector(0.0f, 0.0f, -1.0f));

			FVector OrientedExternalForce = ExternalForce;
			if(!OrientedExternalForce.IsNearlyZero())

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

Scope (from outer to inner):

file
function     void FAnimNode_AnimDynamics::InitPhysics

Source code excerpt:

		if (UPhysicsSettings* Settings = UPhysicsSettings::Get())
		{
			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/Private/BoneControllers/AnimNode_RigidBody.cpp:197

Scope (from outer to inner):

file
function     FAnimNode_RigidBody::FAnimNode_RigidBody

Source code excerpt:

	, LastEvalTimeSeconds(0.0)
	, AccumulatedDeltaTime(0.0f)
	, AnimPhysicsMinDeltaTime(0.0f)
	, bSimulateAnimPhysicsAfterReset(false)
	, SkelMeshCompWeakPtr()
	, PhysicsSimulation(nullptr)
	, SolverSettings()
	, SolverIterations()
	, SimulationTask()

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Private/BoneControllers/AnimNode_RigidBody.cpp:704

Scope (from outer to inner):

file
function     void FAnimNode_RigidBody::EvaluateSkeletalControl_AnyThread

Source code excerpt:


		// Only need to tick physics if we didn't reset and we have some time to simulate
		const bool bNeedsSimulationTick = ((bSimulateAnimPhysicsAfterReset || (ResetSimulatedTeleportType != ETeleportType::ResetPhysics)) && DeltaSeconds > AnimPhysicsMinDeltaTime);
		if (bNeedsSimulationTick)
		{
			// Transfer bone velocities previously captured.
			if (bTransferBoneVelocities && (CapturedBoneVelocityPose.GetPose().GetNumBones() > 0))
			{
				for (const FOutputBoneData& OutputData : OutputBoneData)

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Private/BoneControllers/AnimNode_RigidBody.cpp:1050

Scope (from outer to inner):

file
function     void FAnimNode_RigidBody::InitPhysics

Source code excerpt:

	if (UPhysicsSettings* Settings = UPhysicsSettings::Get())
	{
		AnimPhysicsMinDeltaTime = Settings->AnimPhysicsMinDeltaTime;
		bSimulateAnimPhysicsAfterReset = Settings->bSimulateAnimPhysicsAfterReset;
	}
	else
	{
		AnimPhysicsMinDeltaTime = 0.f;
		bSimulateAnimPhysicsAfterReset = false;
	}
	
	bEnabled = (UsePhysicsAsset && bEnableRigidBodyNode && SkeletalMeshComp->GetAllowRigidBodyAnimNode());
	if(bEnabled)
	{

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

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

#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Public/BoneControllers/AnimNode_RigidBody.h:402

Scope: file

Source code excerpt:


	float AccumulatedDeltaTime;
	float AnimPhysicsMinDeltaTime;
	bool bSimulateAnimPhysicsAfterReset;
	/** This should only be used for removing the delegate during termination. Do NOT use this for any per frame work */
	TWeakObjectPtr<USkeletalMeshComponent> SkelMeshCompWeakPtr;

	ImmediatePhysics::FSimulation* PhysicsSimulation;
	FPhysicsAssetSolverSettings SolverSettings;

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

Scope (from outer to inner):

file
class        class UPhysicsSettings : public UPhysicsSettingsCore

Source code excerpt:

	/** Min Delta Time below which anim dynamics and rigidbody nodes will not simulate. */
	UPROPERTY(config, EditAnywhere, meta = (ClampMin = "0.0", UIMin = "0.0", ClampMax = "1.0", UIMax = "1.0"), Category = Framerate)
	float AnimPhysicsMinDeltaTime;

	/** Whether to simulate anim physics nodes in the tick where they're reset. */
	UPROPERTY(config, EditAnywhere, Category = Simulation)
	bool bSimulateAnimPhysicsAfterReset;

	/** Min Physics Delta Time; the simulation will not step if the delta time is below this value */

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

Scope (from outer to inner):

file
function     UPhysicsSettings::UPhysicsSettings

Source code excerpt:

	, bSuppressFaceRemapTable(false)
	, bDisableActiveActors(false)
	, AnimPhysicsMinDeltaTime(0.f)
	, bSimulateAnimPhysicsAfterReset(false)
	, MinPhysicsDeltaTime(UE_SMALL_NUMBER)
	, MaxPhysicsDeltaTime(1.f / 30.f)
	, bSubstepping(false)
	, bTickPhysicsAsync(false)
	, AsyncFixedTimeStepSize(1.f / 30.f)