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:
- Animation system, specifically in the AnimDynamics and RigidBody animation nodes
- 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:
- bSimulateAnimPhysicsAfterReset
- MaxPhysicsDeltaTime
- MaxSubstepDeltaTime
- MaxSubsteps
Developers must be aware of the following when using this variable:
- Setting it too low may result in performance issues due to frequent physics updates.
- Setting it too high may cause animation physics to appear less smooth or responsive.
- It affects the behavior of AnimDynamics and RigidBody animation nodes.
Best practices when using this variable include:
- Adjust the value based on the specific needs of your project, considering both performance and visual quality.
- Test different values to find the optimal balance between simulation accuracy and performance.
- Consider the target frame rate of your project when setting this value.
- 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]
- INI Section:
/Script/Engine.PhysicsSettings
- Raw value:
0.000000
- Is Array:
False
#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)