p.CharacterStuckWarningPeriod
p.CharacterStuckWarningPeriod
#Overview
name: p.CharacterStuckWarningPeriod
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
How often (in seconds) we are allowed to log a message about being stuck in geometry.\n<0: Disable, >=0: Enable and log this often, in seconds.
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:
- A value less than 0 disables the stuck warning messages.
- A value of 0 or greater enables the warnings, with the value determining the minimum time (in seconds) between logged messages.
- 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:
- Keep it enabled (with a reasonable interval) during development to catch potential issues with character movement and level geometry.
- Consider disabling it (set to -1) in shipping builds to avoid potential performance impacts from frequent logging.
- 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:
- It’s used directly in the character movement code to determine when to log stuck warnings.
- It’s defined within the CharacterMovementCVars namespace, indicating its specific use for character movement.
- The variable is used in both the synchronous (UCharacterMovementComponent) and asynchronous (FCharacterMovementComponentAsyncInput) parts of the character movement system.
- Developers should generally interact with this variable through the p.CharacterStuckWarningPeriod console variable rather than modifying StuckWarningPeriod directly in code.
#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);
}