AgentMaxStepHeight

AgentMaxStepHeight

#Overview

name: AgentMaxStepHeight

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 15 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of AgentMaxStepHeight is to define the largest vertical step that an AI agent can perform when navigating through the game world using the navigation mesh. This setting is crucial for the navigation system in Unreal Engine 5.

AgentMaxStepHeight is primarily used in the NavigationSystem module, specifically within the RecastNavMesh subsystem. This variable is essential for generating and configuring the navigation mesh, which AI agents use for pathfinding.

The value of this variable is typically set in the ARecastNavMesh class, which is a subclass of ANavigationData. It can be configured through the Unreal Engine editor or programmatically in C++ code.

AgentMaxStepHeight interacts with other navigation-related variables such as AgentHeight, AgentMaxSlope, and CellHeight. These variables collectively define the navigation capabilities of AI agents in the game world.

Developers should be aware that:

  1. AgentMaxStepHeight is resolution-dependent, meaning it can have different values for different navigation data resolutions.
  2. As of Unreal Engine 5.3, the single AgentMaxStepHeight property is deprecated in favor of setting it for specific resolutions using NavMeshResolutionParams.
  3. This variable directly affects the walkableClimb parameter in the navigation mesh generation process.

Best practices when using this variable include:

  1. Set appropriate values based on the game’s AI agent capabilities and level design.
  2. Ensure consistency between AgentMaxStepHeight and other related navigation parameters.
  3. Use the new resolution-specific setter (SetAgentMaxStepHeight) instead of directly modifying the deprecated property.
  4. Consider the performance implications of setting very high values, as it may increase the complexity of the generated navigation mesh.
  5. Validate that AgentMaxStepHeight is sufficient for the AgentMaxSlope angle to avoid potential navigation issues.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2825, section: [/Script/NavigationSystem.RecastNavMesh]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavLinkRenderingComponent.cpp:184

Scope (from outer to inner):

file
function     void FNavLinkRenderingProxy::GetDynamicMeshElements

Source code excerpt:

					AgentMask = NavMesh->IsDrawingEnabled() ? AgentMask | (1 << DataIndex) : AgentMask;
#if WITH_RECAST
					const float AgentMaxStepHeight = NavMesh->GetAgentMaxStepHeight(ENavigationDataResolution::Default);
					if (AgentMaxStepHeight > 0 && NavMesh->IsDrawingEnabled())
					{
						StepHeights.Add(AgentMaxStepHeight);
					}
#endif // WITH_RECAST
				}
			}
		}

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:431

Scope (from outer to inner):

file
function     FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties

Source code excerpt:

	AgentHeight = 144.f;
	AgentMaxSlope = 44.f;
	AgentMaxStepHeight = 35.f;
	MinRegionArea = 0.f;
	MergeRegionSize = 400.f;
	MaxSimplificationError = 1.3f;	// from RecastDemo
	TileNumberHardLimit = 1 << 20;
	RegionPartitioning = ERecastPartitioning::Watershed;
	LayerPartitioning = ERecastPartitioning::Watershed;

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:463

Scope (from outer to inner):

file
function     FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties

Source code excerpt:

	AgentHeight = RecastNavMesh.AgentHeight;
	AgentMaxSlope = RecastNavMesh.AgentMaxSlope;
	AgentMaxStepHeight = RecastNavMesh.GetAgentMaxStepHeight(ENavigationDataResolution::Default); //FRecastNavMeshGenerationProperties is getting deprecated 
	MinRegionArea = RecastNavMesh.MinRegionArea;
	MergeRegionSize = RecastNavMesh.MergeRegionSize;
	MaxSimplificationError = RecastNavMesh.MaxSimplificationError;
	TileNumberHardLimit = RecastNavMesh.TileNumberHardLimit;
	RegionPartitioning = RecastNavMesh.RegionPartitioning;
	LayerPartitioning = RecastNavMesh.LayerPartitioning;

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:694

Scope (from outer to inner):

file
function     void ARecastNavMesh::PostLoad

Source code excerpt:

	}

	// If needed, initialize AgentMaxStepHeight from the deprecated value.
	if (NavMeshVersion < NAVMESHVER_TILE_RESOLUTIONS_AGENTMAXSTEPHEIGHT)
	{
		for (int i = 0; i < (uint8)ENavigationDataResolution::MAX; ++i)
		{
			SetAgentMaxStepHeight((ENavigationDataResolution)i, AgentMaxStepHeight);
		}
	}
	PRAGMA_ENABLE_DEPRECATION_WARNINGS
	
	for (uint8 Index = 0; Index < (uint8)ENavigationDataResolution::MAX; Index++)
	{

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:811

Scope (from outer to inner):

file
function     void ARecastNavMesh::PostInitProperties

Source code excerpt:

			}

			const float CurrentAgentMaxStepHeight = NavMeshResolutionParams[i].AgentMaxStepHeight;
			const float DefaultObjectAgentMaxStepHeight = DefOb->NavMeshResolutionParams[i].AgentMaxStepHeight;
			if (CurrentAgentMaxStepHeight != DefaultObjectAgentMaxStepHeight)
			{
				UE_LOG(LogNavigation, Warning, TEXT("%s param: AgentMaxStepHeight(%f) differs from config settings, forcing value %f so it can be used with voxel cache!"),
					*GetNameSafe(this), CurrentAgentMaxStepHeight, DefaultObjectAgentMaxStepHeight);

				NavMeshResolutionParams[i].AgentMaxStepHeight = DefaultObjectAgentMaxStepHeight;
			}			
		}

		if (AgentMaxSlope != DefOb->AgentMaxSlope)
		{
			UE_LOG(LogNavigation, Warning, TEXT("%s param: AgentMaxSlope(%f) differs from config settings, forcing value %f so it can be used with voxel cache!"),

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3445

Scope (from outer to inner):

file
function     void ARecastNavMesh::UpdateGenerationProperties

Source code excerpt:

	AgentMaxSlope = GenerationProps.AgentMaxSlope;

	AgentMaxStepHeight = GenerationProps.AgentMaxStepHeight;

	MinRegionArea = GenerationProps.MinRegionArea;
	MergeRegionSize = GenerationProps.MergeRegionSize;
	MaxSimplificationError = GenerationProps.MaxSimplificationError;
	TileNumberHardLimit = GenerationProps.TileNumberHardLimit;
	RegionPartitioning = GenerationProps.RegionPartitioning;

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4643

Scope (from outer to inner):

file
function     void FRecastNavMeshGenerator::SetupTileConfig

Source code excerpt:

	const float CellSize = GetOwner()->GetCellSize(TileResolution);
	const float CellHeight = GetOwner()->GetCellHeight(TileResolution);
	const float AgentMaxStepHeight = GetOwner()->GetAgentMaxStepHeight(TileResolution);
	
	// Update all settings that depends directly or indirectly of the CellSize
	OutConfig.TileResolution = TileResolution;
	OutConfig.cs = CellSize;
	OutConfig.walkableRadius = FMath::CeilToInt(DestNavMesh->AgentRadius / CellSize);
	OutConfig.maxStepFromWalkableSlope = OutConfig.cs * FMath::Tan(FMath::DegreesToRadians(OutConfig.walkableSlopeAngle));

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4667

Scope (from outer to inner):

file
function     void FRecastNavMeshGenerator::SetupTileConfig

Source code excerpt:

	OutConfig.ch = CellHeight;
	OutConfig.walkableHeight = DestNavMesh->bMarkLowHeightAreas ? 1 : FMath::CeilToInt(DestNavMesh->AgentHeight / CellHeight);
	OutConfig.walkableClimb = FMath::CeilToInt(AgentMaxStepHeight / CellHeight);

	// Update all settings that depends directly or indirectly of AgentMaxStepHeight
	OutConfig.AgentMaxClimb = AgentMaxStepHeight;

	OutConfig.bIsTileSetupConfigCompleted = true;
}

void FRecastNavMeshGenerator::ConfigureBuildProperties(FRecastBuildConfig& OutConfig)
{

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4695

Scope (from outer to inner):

file
function     void FRecastNavMeshGenerator::ConfigureBuildProperties

Source code excerpt:

	OutConfig.maxStepFromWalkableSlope = OutConfig.cs * FMath::Tan(FMath::DegreesToRadians(OutConfig.walkableSlopeAngle));
	
	// For each navmesh resolutions, validate that AgentMaxStepHeight is high enough for the AgentMaxSlope angle
	for (int32 Index = 0; Index < (uint8)ENavigationDataResolution::MAX; Index++)
	{
		const ENavigationDataResolution Resolution = (ENavigationDataResolution)Index;
		
		const float MaxStepHeight = DestNavMesh->GetAgentMaxStepHeight(Resolution);
		const float TempCellHeight = DestNavMesh->GetCellHeight(Resolution);

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:362

Scope: file

Source code excerpt:

	/** Largest vertical step the agent can perform */
	UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "0.0"))
	float AgentMaxStepHeight;

	/* The minimum dimension of area. Areas smaller than this will be discarded */
	UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "0.0"))
	float MinRegionArea;

	/* The size limit of regions to be merged with bigger regions (watershed partitioning only) */

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:633

Scope (from outer to inner):

file
function     bool IsValid

Source code excerpt:

	GENERATED_BODY()

	bool IsValid() const { return CellSize > 0.f && CellHeight > 0.f && AgentMaxStepHeight > 0.f; }
	
	/** Horizontal size of voxelization cell */
	UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
	float CellSize = 25.f;

	/** Vertical size of voxelization cell */

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:645

Scope: file

Source code excerpt:

	/** Largest vertical step the agent can perform */
	UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
	float AgentMaxStepHeight = 35.f;
};

UCLASS(config=Engine, defaultconfig, hidecategories=(Input,Rendering,Tags,Transformation,Actor,Layers,Replication), notplaceable, MinimalAPI)
class ARecastNavMesh : public ANavigationData
{
	GENERATED_UCLASS_BODY()

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:792

Scope (from outer to inner):

file
class        class ARecastNavMesh : public ANavigationData

Source code excerpt:

	UE_DEPRECATED(5.3, "Set the AgentMaxStepHeight for the required navmesh resolutions in NavMeshResolutionParams.")
	UPROPERTY(config)
	float AgentMaxStepHeight;

	/* The minimum dimension of area. Areas smaller than this will be discarded */
	UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "0.0"))
	float MinRegionArea;

	/* The size limit of regions to be merged with bigger regions (watershed partitioning only) */

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:803

Scope: file

Source code excerpt:


	/** Maximum vertical deviation between raw contour points to allowing merging (in voxel).
	 * Use a low value (2-5) depending on CellHeight, AgentMaxStepHeight and AgentMaxSlope, to allow more precise contours (also see SimplificationElevationRatio).
	 * Use very high value to deactivate (Recast behavior). */
	UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0"))
	int MaxVerticalMergeError;
	
	/** How much navigable shapes can get simplified - the higher the value the more freedom */
	UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
	float MaxSimplificationError;

#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:1140

Scope: file

Source code excerpt:

	void SetCellHeight(const ENavigationDataResolution Resolution, const float Height) { NavMeshResolutionParams[(uint8)Resolution].CellHeight = Height; }

	/** Get the AgentMaxStepHeight for the given resolution. */
	float GetAgentMaxStepHeight(const ENavigationDataResolution Resolution) const { return NavMeshResolutionParams[(uint8)Resolution].AgentMaxStepHeight; }

	/** Set the AgentMaxStepHeight for the given resolution. */
	void SetAgentMaxStepHeight(const ENavigationDataResolution Resolution, const float MaxStepHeight) { NavMeshResolutionParams[(uint8)Resolution].AgentMaxStepHeight = MaxStepHeight; }
	
	/** Returns the tile size in world units. */
	NAVIGATIONSYSTEM_API float GetTileSizeUU() const;
	
	/** Whether NavMesh should adjust its tile pool size when NavBounds are changed */
	NAVIGATIONSYSTEM_API bool IsResizable() const;