CellHeight
CellHeight
#Overview
name: CellHeight
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 23
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of CellHeight is to define the vertical size of voxelization cells used in the generation of navigation meshes within Unreal Engine’s navigation system. It is a crucial parameter that affects the precision and performance of pathfinding and navigation in 3D environments.
CellHeight is primarily used by the Recast navigation mesh system, which is part of Unreal Engine’s navigation module. This variable is referenced in various parts of the engine, including:
- The Paper2D plugin for 2D sprite extraction
- The core navigation system, particularly in the RecastNavMesh and RecastNavMeshGenerator classes
The value of CellHeight is typically set in the ARecastNavMesh class, which inherits from ANavigationData. It can be configured through the Unreal Engine editor or programmatically.
CellHeight interacts with several other variables, including:
- CellSize (horizontal size of voxelization cells)
- AgentHeight (height of the navigating agent)
- AgentMaxStepHeight (maximum vertical step the agent can take)
- AgentMaxSlope (maximum slope the agent can traverse)
Developers must be aware that:
- CellHeight directly affects the vertical precision of the navigation mesh. Smaller values increase precision but also increase memory usage and generation time.
- It should be balanced with CellSize to maintain a reasonable aspect ratio for voxels.
- The value should be appropriate for the scale of your game world and the size of your agents.
Best practices when using CellHeight include:
- Adjust it in conjunction with other navigation parameters to achieve the desired balance between precision and performance.
- Use the NavMeshResolutionParams array to set different CellHeight values for different navigation data resolutions, allowing for more flexible and optimized navigation meshes.
- Ensure that CellHeight is small enough to capture important vertical features in your environment but large enough to maintain reasonable performance.
- Consider the relationship between CellHeight and AgentMaxStepHeight when configuring your navigation mesh.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:2818, section: [/Script/NavigationSystem.RecastNavMesh]
- INI Section:
/Script/NavigationSystem.RecastNavMesh
- Raw value:
10.f
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/2D/Paper2D/Source/Paper2DEditor/Private/ExtractSprites/PaperExtractSpritesSettings.h:67
Scope (from outer to inner):
file
class class UPaperExtractSpriteGridSettings : public UObject
Source code excerpt:
// The height of each sprite in grid mode
UPROPERTY(Category = Grid, EditAnywhere, meta = (UIMin = 1, ClampMin = 1))
int32 CellHeight = 64;
// Number of cells extracted horizontally. Can be used to limit the number of sprites extracted. Set to 0 to extract all sprites
UPROPERTY(Category = Grid, EditAnywhere, meta = (UIMin = 0, ClampMin = 0))
int32 NumCellsX;
// Number of cells extracted vertically. Can be used to limit the number of sprites extracted. Set to 0 to extract all sprites
#Loc: <Workspace>/Engine/Plugins/2D/Paper2D/Source/Paper2DEditor/Private/ExtractSprites/SPaperExtractSpritesDialog.cpp:163
Scope (from outer to inner):
file
function void SPaperExtractSpritesDialog::Construct
Source code excerpt:
ExtractSpriteGridSettings->AddToRoot();
ExtractSpriteGridSettings->CellWidth = InSourceTexture->GetImportedSize().X;
ExtractSpriteGridSettings->CellHeight = InSourceTexture->GetImportedSize().Y;
PreviewExtractedSprites();
FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs DetailsViewArgs;
DetailsViewArgs.bAllowSearch = false;
#Loc: <Workspace>/Engine/Plugins/2D/Paper2D/Source/Paper2DEditor/Private/ExtractSprites/SPaperExtractSpritesDialog.cpp:364
Scope (from outer to inner):
file
function void SPaperExtractSpritesDialog::PreviewExtractedSprites
Source code excerpt:
const int32 EffectiveCellWidth = FMath::Clamp(ExtractSpriteGridSettings->CellWidth, 1, TextureWidth);
const int32 EffectiveCellHeight = FMath::Clamp(ExtractSpriteGridSettings->CellHeight, 1, TextureHeight);
int NumExtractedCellsY = 0;
for (int32 Y = ExtractSpriteGridSettings->MarginY; Y + EffectiveCellHeight <= TextureHeight; Y += EffectiveCellHeight + ExtractSpriteGridSettings->SpacingY)
{
int NumExtractedCellsX = 0;
for (int32 X = ExtractSpriteGridSettings->MarginX; X + EffectiveCellWidth <= TextureWidth; X += EffectiveCellWidth + ExtractSpriteGridSettings->SpacingX)
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:427
Scope (from outer to inner):
file
function FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties
Source code excerpt:
TileSizeUU = 988.f;
CellSize = 19;
CellHeight = 10;
AgentRadius = 34.f;
AgentHeight = 144.f;
AgentMaxSlope = 44.f;
AgentMaxStepHeight = 35.f;
MinRegionArea = 0.f;
MergeRegionSize = 400.f;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:459
Scope (from outer to inner):
file
function FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties
Source code excerpt:
CellSize = RecastNavMesh.GetCellSize(ENavigationDataResolution::Default);
CellHeight = RecastNavMesh.GetCellHeight(ENavigationDataResolution::Default);
AgentRadius = RecastNavMesh.AgentRadius;
AgentHeight = RecastNavMesh.AgentHeight;
AgentMaxSlope = RecastNavMesh.AgentMaxSlope;
AgentMaxStepHeight = RecastNavMesh.GetAgentMaxStepHeight(ENavigationDataResolution::Default); //FRecastNavMeshGenerationProperties is getting deprecated
MinRegionArea = RecastNavMesh.MinRegionArea;
MergeRegionSize = RecastNavMesh.MergeRegionSize;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:685
Scope (from outer to inner):
file
function void ARecastNavMesh::PostLoad
Source code excerpt:
}
// If needed, initialize CellHeight from the deprecated value.
if (NavMeshVersion < NAVMESHVER_TILE_RESOLUTIONS_CELLHEIGHT)
{
for (int i = 0; i < (uint8)ENavigationDataResolution::MAX; ++i)
{
SetCellHeight((ENavigationDataResolution)i, CellHeight);
}
}
// If needed, initialize AgentMaxStepHeight from the deprecated value.
if (NavMeshVersion < NAVMESHVER_TILE_RESOLUTIONS_AGENTMAXSTEPHEIGHT)
{
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:801
Scope (from outer to inner):
file
function void ARecastNavMesh::PostInitProperties
Source code excerpt:
}
const float CurrentCellHeight = NavMeshResolutionParams[i].CellHeight;
const float DefaultObjectCellHeight = DefOb->NavMeshResolutionParams[i].CellHeight;
if (CurrentCellHeight != DefaultObjectCellHeight)
{
UE_LOG(LogNavigation, Warning, TEXT("%s param: CellHeight(%f) differs from config settings, forcing value %f so it can be used with voxel cache!"),
*GetNameSafe(this), CurrentCellHeight, DefaultObjectCellHeight);
NavMeshResolutionParams[i].CellHeight = DefaultObjectCellHeight;
}
const float CurrentAgentMaxStepHeight = NavMeshResolutionParams[i].AgentMaxStepHeight;
const float DefaultObjectAgentMaxStepHeight = DefOb->NavMeshResolutionParams[i].AgentMaxStepHeight;
if (CurrentAgentMaxStepHeight != DefaultObjectAgentMaxStepHeight)
{
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3251
Scope (from outer to inner):
file
function void ARecastNavMesh::PostEditChangeChainProperty
Source code excerpt:
}
}
else if (PropName == GET_MEMBER_NAME_CHECKED(FNavMeshResolutionParam, CellHeight))
{
PRAGMA_DISABLE_DEPRECATION_WARNINGS
// Update the deprecated CellHeight to fit the default resolution CellHeight
CellHeight = NavMeshResolutionParams[(uint8)ENavigationDataResolution::Default].CellHeight;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
bRebuild = true;
}
if (bRebuild)
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3439
Scope (from outer to inner):
file
function void ARecastNavMesh::UpdateGenerationProperties
Source code excerpt:
CellSize = GenerationProps.CellSize;
CellHeight = GenerationProps.CellHeight;
AgentRadius = GenerationProps.AgentRadius;
AgentHeight = GenerationProps.AgentHeight;
AgentMaxSlope = GenerationProps.AgentMaxSlope;
AgentMaxStepHeight = GenerationProps.AgentMaxStepHeight;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:1579
Scope (from outer to inner):
file
function void Create
Source code excerpt:
}
void Create(int32 FieldSize, FVector::FReal CellSize, FVector::FReal CellHeight)
{
if (RasterizeHF == NULL)
{
const FVector::FReal DummyBounds[3] = { 0 };
RasterizeHF = rcAllocHeightfield();
rcCreateHeightfield(NULL, *RasterizeHF, FieldSize, FieldSize, DummyBounds, DummyBounds, CellSize, CellHeight);
}
}
void Reset()
{
rcResetHeightfield(*RasterizeHF);
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:2179
Scope (from outer to inner):
file
function void FRecastTileGenerator::ApplyVoxelFilter
Source code excerpt:
const int32 Height = HF->height;
const FVector::FReal CellSize = HF->cs;
const FVector::FReal CellHeight = HF->ch;
const FVector::FReal BottomX = HF->bmin[0];
const FVector::FReal BottomZ = HF->bmin[1];
const FVector::FReal BottomY = HF->bmin[2];
const int32 SpansCount = Width*Height;
// we need to expand considered bounding boxes so that
// it doesn't create "fake cliffs"
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:2208
Scope (from outer to inner):
file
function void FRecastTileGenerator::ApplyVoxelFilter
Source code excerpt:
if (s->data.area == RC_WALKABLE_AREA)
{
const FVector::FReal SpanMin = CellHeight * s->data.smin + BottomZ;
const FVector::FReal SpanMax = CellHeight * s->data.smax + BottomZ;
const FVector SpanMinV(SpanX-CellSize, SpanY-CellSize, SpanMin);
const FVector SpanMaxV(SpanX, SpanY, SpanMax);
if (BB.IsInside(SpanMinV) == false && BB.IsInside(SpanMaxV) == false)
{
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:2249
Scope (from outer to inner):
file
function void FRecastTileGenerator::ApplyVoxelFilter
Source code excerpt:
if (s->data.area == RC_WALKABLE_AREA)
{
const FVector::FReal SpanMin = CellHeight * s->data.smin + BottomZ;
const FVector::FReal SpanMax = CellHeight * s->data.smax + BottomZ;
const FVector SpanMinV(SpanX-CellSize, SpanY-CellSize, SpanMin);
const FVector SpanMaxV(SpanX, SpanY, SpanMax);
bool bIsInsideAnyBB = false;
const FBox* BB = Bounds.GetData();
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4642
Scope (from outer to inner):
file
function void FRecastNavMeshGenerator::SetupTileConfig
Source code excerpt:
ensure(GetConfig().cs == GetOwner()->GetCellSize(ENavigationDataResolution::Default));
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);
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4664
Scope (from outer to inner):
file
function PRAGMA_ENABLE_DEPRECATION_WARNINGS void FRecastNavMeshGenerator::SetupTileConfig
Source code excerpt:
OutConfig.TileCacheChunkSize = FMath::Max(1, OutConfig.tileSize / FMath::Max(1, DestNavMesh->RegionChunkSplits));
// Update all settings that depends directly or indirectly of the CellHeight
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;
}
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4679
Scope (from outer to inner):
file
function void FRecastNavMeshGenerator::ConfigureBuildProperties
Source code excerpt:
// @TODO those variables should be tweakable per navmesh actor
const float CellSize = DestNavMesh->GetCellSize(ENavigationDataResolution::Default);
const float CellHeight = DestNavMesh->GetCellHeight(ENavigationDataResolution::Default);
const float AgentHeight = DestNavMesh->AgentHeight;
const float AgentMaxSlope = DestNavMesh->AgentMaxSlope;
const float AgentMaxClimb = DestNavMesh->GetAgentMaxStepHeight(ENavigationDataResolution::Default);
const float AgentRadius = DestNavMesh->AgentRadius;
OutConfig.Reset();
OutConfig.cs = CellSize;
OutConfig.ch = CellHeight;
OutConfig.walkableSlopeAngle = AgentMaxSlope;
OutConfig.walkableHeight = FMath::CeilToInt(AgentHeight / CellHeight);
OutConfig.walkableClimb = FMath::CeilToInt(AgentMaxClimb / CellHeight);
OutConfig.walkableRadius = FMath::CeilToInt(AgentRadius / CellSize);
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++)
{
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:7309
Scope (from outer to inner):
file
lambda-function
Source code excerpt:
if (Verts.Num())
{
const float CellHeight = NavData->GetCellHeight(ENavigationDataResolution::Default);
Snapshot->AddPulledConvex(
Verts,
InConvexNavAreaData.MinZ - CellHeight,
InConvexNavAreaData.MaxZ + CellHeight,
CategoryName, NavAreaVerbosity, PolygonColor.WithAlpha(255));
}
};
if (ShapeType == ENavigationShapeType::Convex)
{
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:7443
Scope (from outer to inner):
file
lambda-function
lambda-function
Source code excerpt:
if (ConvexVerts.Num())
{
const float CellHeight = NavData->GetCellHeight(ENavigationDataResolution::Default);
ExportInfo.Convex.MinZ -= CellHeight;
ExportInfo.Convex.MaxZ += CellHeight;
ExportInfo.Convex.Points = UE::LWC::ConvertArrayType<FVector>(ConvexVerts);
AreaExport.Add(ExportInfo);
}
};
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:346
Scope: file
Source code excerpt:
/** vertical size of voxelization cell */
UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
float CellHeight;
/** Radius of largest agent that can freely traverse the generated navmesh */
UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "0.0"))
float AgentRadius;
/** Size of the tallest agent that will path with this navmesh. */
#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 */
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
float CellHeight = 10.f;
/** Largest vertical step the agent can perform */
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
float AgentMaxStepHeight = 35.f;
};
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:769
Scope (from outer to inner):
file
class class ARecastNavMesh : public ANavigationData
Source code excerpt:
UE_DEPRECATED(5.2, "Set the CellHeight for the required navmesh resolutions in NavMeshResolutionParams.")
UPROPERTY(config)
float CellHeight;
/** Resolution params
* If using multiple resolutions, it's recommended to chose the highest resolution first and
* set it according to the highest desired precision and then the other resolutions. */
UPROPERTY(EditAnywhere, Category = Generation, config)
FNavMeshResolutionParam NavMeshResolutionParams[(uint8)ENavigationDataResolution::MAX];
#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:1134
Scope: file
Source code excerpt:
void SetCellSize(const ENavigationDataResolution Resolution, const float Size) { NavMeshResolutionParams[(uint8)Resolution].CellSize = Size; }
/** Get the CellHeight for the given resolution. */
float GetCellHeight(const ENavigationDataResolution Resolution) const { return NavMeshResolutionParams[(uint8)Resolution].CellHeight; }
/** Set the CellHeight for the given resolution. */
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; }