AddTorque() malfunctions if using fixed time steps

Version: 4.6.1 (binary release)

The AddTorque() method (Physics / Add Torque in blueprints) malfunctions with skeletal meshes if fixed time steps are being used (-UseFixedTimeStep command line option). Both C++ and Blueprint versions of AddTorque() are affected. AddForce() is not affected, nor is either of these methods with static meshes.

With default physics settings, the effective torque applied by USkeletalMeshComponent::AddTorque() approaches zero as the fixed delta time, set with FApp::SetFixedDeltaTime( dt ), approaches 0.02 from below (50 fps). With dt >= 0.02, AddTorque() will have no effect no matter how big the supplied force argument is.

The following videos illustrate the issue:

dt = 0.015: UE4 AddTorque() and fixed dt bug, dt = 0.015 - YouTube

dt = 0.019: UE4 AddTorque() and fixed dt bug, dt = 0.019 - YouTube

dt = 0.020: UE4 AddTorque() and fixed dt bug, dt = 0.02 - YouTube

If MaxPhysicsDeltaTime (MaxSubstepDeltaTime if using substepping) is set to be smaller than 0.02, then the bug disappears. MaxPhysicsDeltaTime (or MaxSubstepDeltaTime) does not seem to affect things otherwise.

Instructions for reproducing the issue

Initialize the project:

  1. Create a new project using the Basic Code (C++) template, with starter content
  2. Open the Content Examples demo project and migrate the Owen character to your newly created project

Set up the scene:

  1. Disable gravity: Settings (top panel) → World Settings → Override World Gravity = ON
  2. Raise the table into air, so that it does not touch anything
  3. Place an instance of Owen into the scene, in-air, and rename it to “TheOwen”
  4. Enable physics for the table and the Owen actors: select an actor, Details panel → Simulate Physics = ON

Apply torques and forces, Blueprint version:

(To do this in C++, skip this phase and instead copy the code at the end to your project.)

  1. Open the level blueprint, then drag the table (“Table”) and the Owen actor (“TheOwen”) from the Scene Outliner to the Event Graph of the Level Blueprint
  2. Drag from the blue pins of the newly created nodes and create Add Torque and Add Force nodes for both, then connect them properly to an Event Tick node. Set the Z torques/forces as follows:
    Table Z torque = 100,000, Table Z force = 100, TheOwen Z torque = 1,000,000, TheOwen Z force = 100

Hit Play or Simulate so as to test the scene: the Table and the TheOwen actors should start to rotate and rise as seen in the first video.

Save everything and close the editor.

Set the fixed dt:

  1. Open your project in Visual Studio
  2. Open the YourProjectNameGameMode.h file, add this to the class body and recompile:

.

AYourProjectNameGameMode() :
	AGameMode( FObjectInitializer() )
{
	FApp::SetFixedDeltaTime( 0.015f );
}

Enable fixed time steps with the -UseFixedTimeStep command line option:

  1. Create a shortcut from your .uproject file and open the Properties of the newly created shortcut
  2. Edit the Target field to look something like this: “C:\enginepath\UE4Editor.exe” “C:\projectpath\YourProjectName.uproject” -UseFixedTimeStep

Now open your project via the shortcut and hit Play or Simulate. Everything should work normally, but if you change the dt to 0.02 in FApp::SetFixedDeltaTime(), then the bug should become visible.

Apply torques and forces, C++ version:

YourProjectNameGameMode.h, override Tick():

class ADDTORQUEANDDT461_API AAddTorqueAndDt461GameMode : public AGameMode
{
	GENERATED_BODY()

	AYourProjectNameGameMode() :
		AGameMode( FObjectInitializer() )
	{
		FApp::SetFixedDeltaTime( 0.015f );
	}

	void Tick( float dt ) override;
};

YourProjectNameGameMode.cpp:

// Fill out your copyright notice in the Description page of Project Settings.

#include "AddTorqueAndDt461.h"
#include "AddTorqueAndDt461GameMode.h"

#include <Animation/SkeletalMeshActor.h>


void AAddTorqueAndDt461GameMode::Tick( float dt )
{
	Super::Tick( dt );

	UStaticMeshComponent * table = 0;
	USkeletalMeshComponent * owen = 0;

	for( TActorIterator<AStaticMeshActor> ActorItr( GetWorld() ); ActorItr; ++ActorItr )
	{
		if( ActorItr->GetName() == "Table" )
		{
			table = ActorItr->GetStaticMeshComponent();
			break;
		}
	}

	for( TActorIterator<ASkeletalMeshActor> ActorItr( GetWorld() ); ActorItr; ++ActorItr )
	{
		if( ActorItr->GetName() == "TheOwen" )
		{
			owen = ActorItr->GetSkeletalMeshComponent();
			break;
		}
	}

	if( !table || !owen ) {
		UE_LOG( LogTemp, Error, TEXT( "Failed to locate the table or Owen!" ) );
		return;
	}

	table->AddTorque( FVector( 0.f, 0.f, 1e5f ) );
	table->AddForce( FVector( 0.f, 0.f, 100.f ) );
	owen->AddTorque( FVector( 0.f, 0.f, 1e6f ) );
	owen->AddForce( FVector( 0.f, 0.f, 100.f ) );
}

Hi hiili,

Thank you for providing some very clear repro steps for this issue. I followed your steps and was able to see the same results that you described. I did have a clarification question for you, though. Do you only see these results when using the Owen Skeletal Mesh? I ran through the same steps using a different Skeletal Mesh and the torque seemed to be applied correctly. Applying the same amount of torque also seemed like it was rotating the other Skeletal Mesh more rapidly, so I am wondering if the issue might lie in the Owen Skeletal Mesh instead of with AddTorque().

Hi ,

I haven’t tried this with any other skelmesh, so yes, it might well be an Owen issue! May I ask which skelmesh did you use, or actually, is there another skelmesh with full physics support available somewhere for UE subscribers that I could try to use in place of Owen?

Paul

The bug seems to reside somewhere in angular damping code: when I set the angular damping parameters of all “bones with bodies” of Owen to zero (using PhAT), the bug no more affects the simulation. The other model that you used for testing probably had zero angular dampings and thus wasn’t affected?

Sorry for the delay in getting back to you. It does look like the angular damping parameters were contributing to the differences in what we were seeing. The other skeletal mesh that we tested with was just imported, no additional settings were changed so damping was not set. I am going to run some additional tests with different angular damping values set to see if I can narrow down further what is happening.

Hi hiili,

After some additional experimentation, I was able to determine that the only bone that apparently causes this issue with the Owen character is the Pelvis bone. When I set that bone’s Angular Damping parameter to 0, Owen would rotate. Adjusting the Angular Damping parameter for any other bones did not appear to have any affect on Owen’s rotation, or lack thereof. I have submitted a report of what I found to have this investigated further (UE-8349).

A quick update on this issue. It looks like this is actually something internal to PhysX. We have contacted Nvidia and asked them to take a look at it.