P.Chaos.SyncKinematicOnGameThread

P.Chaos.SyncKinematicOnGameThread

#Overview

name: P.Chaos.SyncKinematicOnGameThread

This variable is created as a Console Variable (cvar).

It is referenced in 7 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of P.Chaos.SyncKinematicOnGameThread is to control how kinematic bodies synchronize their transforms between the physics simulation and the game thread in Unreal Engine’s Chaos physics system.

This setting variable is primarily used in the Chaos physics subsystem, which is part of Unreal Engine’s experimental physics implementation. It affects the behavior of kinematic bodies in the physics simulation.

The value of this variable is set through a console variable (CVar) named “P.Chaos.SyncKinematicOnGameThread”. It can be set to 0, 1, or any other value (default is -1).

P.Chaos.SyncKinematicOnGameThread interacts with the UpdateKinematicFromSimulation flag in the BodyInstance class. When set to -1 (default), it delegates the decision to update kinematic bodies to this per-object flag.

Developers must be aware that:

  1. Setting it to 1 forces all kinematic bodies to send their transforms back to the game thread after each simulation step.
  2. Setting it to 0 prevents kinematic bodies from sending transforms back, updating them immediately when their kinematic target is set.
  3. Any other value (including the default -1) makes the behavior dependent on the UpdateKinematicFromSimulation flag for each object.

Best practices when using this variable:

  1. Use the default value (-1) for most scenarios, allowing per-object control through the UpdateKinematicFromSimulation flag.
  2. Set to 1 if you need consistent behavior across all kinematic bodies and want to ensure game thread updates.
  3. Set to 0 if you want immediate updates for kinematic bodies and are handling synchronization manually.

The associated variable SyncKinematicOnGameThread is the actual integer storage for this setting. It’s used in various parts of the Chaos physics implementation to determine the synchronization behavior of kinematic bodies. The same considerations and best practices apply to this associated variable as it directly reflects the console variable setting.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PhysicsProxy/SingleParticlePhysicsProxy.cpp:26

Scope (from outer to inner):

file
namespace    Chaos

Source code excerpt:

// flag on the BodyInstance.
CHAOS_API int32 SyncKinematicOnGameThread = -1;
FAutoConsoleVariableRef CVar_SyncKinematicOnGameThread(TEXT("P.Chaos.SyncKinematicOnGameThread"), 
	SyncKinematicOnGameThread, TEXT(
		"If set to 1, kinematic bodies will always send their transforms back to the game thread, following the "
		"simulation step/results. If 0, then they will never do so, and kinematics will be updated immediately "
		"their kinematic target is set. Any other value (e.g. the default -1) means that the behavior is "
		"determined on a per-object basis with the UpdateKinematicFromSimulation flag in BodyInstance."));

#Associated Variable and Callsites

This variable is associated with another variable named SyncKinematicOnGameThread. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PBDRigidsSolver.cpp:423

Scope (from outer to inner):

file
namespace    Chaos

Source code excerpt:

	using namespace CVars;

	CHAOS_API extern int32 SyncKinematicOnGameThread;

	class AdvanceOneTimeStepTask : public FNonAbandonableTask
	{
		friend class FAutoDeleteAsyncTask<AdvanceOneTimeStepTask>;
	public:
		AdvanceOneTimeStepTask(

#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PBDRigidsSolver.cpp:1757

Scope (from outer to inner):

file
namespace    Chaos
function     bool ShouldUpdateFromSimulation

Source code excerpt:

		if (InRigidParticle.ObjectState() == Chaos::EObjectStateType::Kinematic)
		{
			switch (Chaos::SyncKinematicOnGameThread)
			{
			case 0:
				return false;
			case 1:
				return true;
			default:

#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PhysicsProxy/SingleParticlePhysicsProxy.cpp:25

Scope (from outer to inner):

file
namespace    Chaos

Source code excerpt:

// Velocity and such will still be copied in any case. The default value of -1 uses the UpdateKinematicFromSimulation 
// flag on the BodyInstance.
CHAOS_API int32 SyncKinematicOnGameThread = -1;
FAutoConsoleVariableRef CVar_SyncKinematicOnGameThread(TEXT("P.Chaos.SyncKinematicOnGameThread"), 
	SyncKinematicOnGameThread, TEXT(
		"If set to 1, kinematic bodies will always send their transforms back to the game thread, following the "
		"simulation step/results. If 0, then they will never do so, and kinematics will be updated immediately "
		"their kinematic target is set. Any other value (e.g. the default -1) means that the behavior is "
		"determined on a per-object basis with the UpdateKinematicFromSimulation flag in BodyInstance."));

FSingleParticlePhysicsProxy::FSingleParticlePhysicsProxy(TUniquePtr<PARTICLE_TYPE>&& InParticle, FParticleHandle* InHandle, UObject* InOwner)

#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PhysicsProxy/SingleParticlePhysicsProxy.cpp:258

Scope (from outer to inner):

file
namespace    Chaos
function     bool ShouldUpdateTransformFromSimulation

Source code excerpt:

	if (Rigid.ObjectState() == Chaos::EObjectStateType::Kinematic)
	{
		switch (Chaos::SyncKinematicOnGameThread)
		{
		case 0:
			return false;
		case 1:
			return true;
		default:

#Loc: <Workspace>/Engine/Source/Runtime/PhysicsCore/Private/ChaosEngineInterface.cpp:35

Scope (from outer to inner):

file
namespace    Chaos

Source code excerpt:

	extern CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic;
	extern CHAOS_API int32 AccelerationStructureIsolateQueryOnlyObjects;
	extern CHAOS_API int32 SyncKinematicOnGameThread;
}

bool bEnableChaosJointConstraints = true;
FAutoConsoleVariableRef CVarEnableChaosJointConstraints(TEXT("p.ChaosSolverEnableJointConstraints"), bEnableChaosJointConstraints, TEXT("Enable Joint Constraints defined within the Physics Asset Editor"));

bool bEnableChaosCollisionManager = true;

#Loc: <Workspace>/Engine/Source/Runtime/PhysicsCore/Private/ChaosEngineInterface.cpp:2195

Scope: file

Source code excerpt:

}

// Match the logic in places that use SyncKinematicOnGameThread (like
// FSingleParticlePhysicsProxy::PullFromPhysicsState) - to see if that will be updating the
// position. If not, then we need to do it here. 
bool ShouldSetKinematicTargetSetGameTransform(const FPhysicsActorHandle& InActorReference)
{
	Chaos::FPBDRigidParticle* Rigid = InActorReference->GetRigidParticleUnsafe();
	if (Rigid && Rigid->ObjectState() == Chaos::EObjectStateType::Kinematic)
	{
		switch (Chaos::SyncKinematicOnGameThread)
		{
		case 0:
			return true;
		case 1:
			return false;
		default: