p.CharacterStuckWarningPeriod

p.CharacterStuckWarningPeriod

#Overview

name: p.CharacterStuckWarningPeriod

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

It is referenced in 4 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of p.CharacterStuckWarningPeriod is to control the frequency of logging messages when a character gets stuck in geometry during movement.

This setting variable is primarily used by the Character Movement system in Unreal Engine 5. It is part of the Engine module, specifically within the CharacterMovementComponent.

The value of this variable is set through a console variable (CVar) system. It’s initialized with a default value of 1.0 seconds in non-shipping builds and -1.0 seconds (disabled) in shipping builds. Developers can modify this value at runtime using console commands.

The associated variable StuckWarningPeriod directly interacts with p.CharacterStuckWarningPeriod. They share the same value, with StuckWarningPeriod being the internal representation used in the C++ code.

Developers should be aware that:

  1. A value less than 0 disables the stuck warning messages.
  2. A value of 0 or greater enables the warnings, with the value determining the minimum time (in seconds) between logged messages.
  3. This setting affects both the frequency of log messages and the behavior of the ensure() macro, which can impact performance in development builds.

Best practices when using this variable include:

  1. Keep it enabled (with a reasonable interval) during development to catch potential issues with character movement and level geometry.
  2. Consider disabling it (set to -1) in shipping builds to avoid potential performance impacts from frequent logging.
  3. Adjust the value based on the needs of your project - lower values provide more frequent feedback but could spam the log if characters get stuck often.

Regarding the associated variable StuckWarningPeriod:

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:155

Scope (from outer to inner):

file
namespace    CharacterMovementCVars

Source code excerpt:


	FAutoConsoleVariableRef CVarStuckWarningPeriod(
		TEXT("p.CharacterStuckWarningPeriod"),
		StuckWarningPeriod,
		TEXT("How often (in seconds) we are allowed to log a message about being stuck in geometry.\n")
		TEXT("<0: Disable, >=0: Enable and log this often, in seconds."),
		ECVF_Default);

	static int32 NetEnableMoveCombining = 1;

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/CharacterMovementComponentAsync.cpp:3208

Scope (from outer to inner):

file
function     void FCharacterMovementComponentAsyncInput::OnCharacterStuckInGeometry

Source code excerpt:

void FCharacterMovementComponentAsyncInput::OnCharacterStuckInGeometry(const FHitResult* Hit, FCharacterMovementComponentAsyncOutput& Output) const 
{
	/*if (CharacterMovementCVars::StuckWarningPeriod >= 0)
	{
		const UWorld* MyWorld = World;
		const float RealTimeSeconds = MyWorld->GetRealTimeSeconds();
		if ((RealTimeSeconds - LastStuckWarningTime) >= CharacterMovementCVars::StuckWarningPeriod)
		{
			LastStuckWarningTime = RealTimeSeconds;
			if (Hit == nullptr)
			{
				UE_LOG(LogCharacterMovement, Log, TEXT("%s is stuck and failed to move! (%d other events since notify)"), *CharacterOwner->GetName(), StuckWarningCountSinceNotify);
			}
			else
			{
				UE_LOG(LogCharacterMovement, Log, TEXT("%s is stuck and failed to move! Velocity: X=%3.2f Y=%3.2f Z=%3.2f Location: X=%3.2f Y=%3.2f Z=%3.2f Normal: X=%3.2f Y=%3.2f Z=%3.2f PenetrationDepth:%.3f Actor:%s Component:%s BoneName:%s (%d other events since notify)"),
					*GetNameSafe(CharacterOwner),
					Velocity.X, Velocity.Y, Velocity.Z,
					Hit->Location.X, Hit->Location.Y, Hit->Location.Z,
					Hit->Normal.X, Hit->Normal.Y, Hit->Normal.Z,
					Hit->PenetrationDepth,
					*GetNameSafe(Hit->GetActor()),
					*GetNameSafe(Hit->GetComponent()),
					Hit->BoneName.IsValid() ? *Hit->BoneName.ToString() : TEXT("None"),
					StuckWarningCountSinceNotify
				);
			}
			ensure(false);
			StuckWarningCountSinceNotify = 0;
		}
		else
		{
			StuckWarningCountSinceNotify += 1;
		}
	}*/

	// Don't update velocity based on our (failed) change in position this update since we're stuck.
	Output.bJustTeleported = true;
}

bool FCharacterMovementComponentAsyncInput::CanStepUp(const FHitResult& Hit, FCharacterMovementComponentAsyncOutput& Output) const
{
	if (!Hit.IsValidBlockingHit() || !bHasValidData || Output.MovementMode == MOVE_Falling)
	{
		return false;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:149

Scope (from outer to inner):

file
namespace    CharacterMovementCVars

Source code excerpt:

	// Logging when character is stuck. Off by default in shipping.
#if UE_BUILD_SHIPPING
	static float StuckWarningPeriod = -1.f;
#else
	static float StuckWarningPeriod = 1.f;
#endif

	FAutoConsoleVariableRef CVarStuckWarningPeriod(
		TEXT("p.CharacterStuckWarningPeriod"),
		StuckWarningPeriod,
		TEXT("How often (in seconds) we are allowed to log a message about being stuck in geometry.\n")
		TEXT("<0: Disable, >=0: Enable and log this often, in seconds."),
		ECVF_Default);

	static int32 NetEnableMoveCombining = 1;
	FAutoConsoleVariableRef CVarNetEnableMoveCombining(

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:5229

Scope (from outer to inner):

file
function     void UCharacterMovementComponent::OnCharacterStuckInGeometry

Source code excerpt:

void UCharacterMovementComponent::OnCharacterStuckInGeometry(const FHitResult* Hit)
{
	if (CharacterMovementCVars::StuckWarningPeriod >= 0)
	{
		const UWorld* MyWorld = GetWorld();
		const float RealTimeSeconds = MyWorld->GetRealTimeSeconds();
		if ((RealTimeSeconds - LastStuckWarningTime) >= CharacterMovementCVars::StuckWarningPeriod)
		{
			LastStuckWarningTime = RealTimeSeconds;
			if (Hit == nullptr)
			{
				UE_LOG(LogCharacterMovement, Log, TEXT("%s is stuck and failed to move! (%d other events since notify)"), *CharacterOwner->GetName(), StuckWarningCountSinceNotify);
			}