TileSizeUU
TileSizeUU
#Overview
name: TileSizeUU
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 19
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of TileSizeUU is to define the size of a single navigation mesh tile in Unreal Engine units. This variable is crucial for the navigation system, specifically for the Recast navigation mesh generation.
TileSizeUU is primarily used in the NavigationSystem module, particularly within the RecastNavMesh subsystem. It’s a key parameter in the generation and configuration of navigation meshes.
The value of this variable is typically set in the ARecastNavMesh class constructor or through the Unreal Engine editor interface. It can also be modified programmatically, but with certain restrictions and validations.
TileSizeUU interacts with several other variables, notably:
- CellSize: TileSizeUU must be larger than CellSize.
- AgentRadius: Used in calculations to ensure the tile size is appropriate for the agent.
Developers must be aware of the following when using this variable:
- TileSizeUU has a minimum value constraint (300.0 units).
- It affects performance and memory usage; larger tiles consume more memory but may reduce the number of tiles needed.
- Changing TileSizeUU requires regeneration of the navigation mesh.
- It’s used in various calculations, including area measurements and time estimations for navigation mesh generation.
Best practices when using TileSizeUU include:
- Ensure it’s set to a value that’s a multiple of the CellSize for optimal performance.
- Balance between memory usage and generation time when choosing a value.
- Consider the size of your game world and typical obstacles when setting this value.
- Avoid changing it frequently, as it requires full regeneration of the navigation mesh.
- Use the provided clamping functions (like UE::NavMesh::Private::GetClampedTileSizeUU) when modifying the value to ensure it stays within valid ranges.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:2816, section: [/Script/NavigationSystem.RecastNavMesh]
- INI Section:
/Script/NavigationSystem.RecastNavMesh
- Raw value:
1000.f
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/NavMeshRenderingComponent.cpp:633
Scope (from outer to inner):
file
function void FNavMeshSceneProxyData::GatherData
Source code excerpt:
DebugLabels.Add(FDebugText(TEXT(""))); // empty line
const double TileAreaM2 = FMath::Square(NavMesh->TileSizeUU) / 10000.;
const double TotalAreaM2 = DebugDataMap->Num() * TileAreaM2;
const double TimePer100M2Ms = (TotalTileBuildTime / (TotalAreaM2/100.)) * 1000.;
DebugLabels.Add(FDebugText(FString::Printf(TEXT("Time per 100m2: %0.2f ms"), TimePer100M2Ms)));
const double TimePerSqKmS = TotalTileBuildTime / (TotalAreaM2/1000000.);
DebugLabels.Add(FDebugText(FString::Printf(TEXT("Time per km2: %0.3f s"), TimePerSqKmS)));
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/NavMeshRenderingComponent.cpp:821
Scope (from outer to inner):
file
function void FNavMeshSceneProxyData::GatherData
Source code excerpt:
FNavLocation NavLocation(TileLabelLocation);
if (!NavMesh->ProjectPoint(TileLabelLocation, NavLocation, FVector(NavMesh->TileSizeUU / 100, NavMesh->TileSizeUU / 100, TileBoundingBox.Max.Z - TileBoundingBox.Min.Z)))
{
NavMesh->ProjectPoint(TileLabelLocation, NavLocation, FVector(NavMesh->TileSizeUU / 2, NavMesh->TileSizeUU / 2, TileBoundingBox.Max.Z - TileBoundingBox.Min.Z));
}
if (bGatherTileLabels)
{
DebugLabels.Add(FDebugText(NavLocation.Location + NavMeshDrawOffset, FString::Printf(TEXT("(%d,%d:%d)"), X, Y, Layer)));
}
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/PImplRecastNavMesh.cpp:606
Scope (from outer to inner):
file
function void FPImplRecastNavMesh::Serialize
Source code excerpt:
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
const FVector::FReal ActorsTileSize = FVector::FReal(int32(NavMeshOwner->TileSizeUU / DefaultCellSize) * DefaultCellSize);
if (ActorsTileSize != Params.tileWidth)
{
// just move archive position
ReleaseDetourNavMesh();
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:64
Scope (from outer to inner):
file
namespace UE::NavMesh::Private
Source code excerpt:
constexpr int32 ArbitraryMinTileSizeAgentRadius = 4;
/** this helper function supplies a consistent way to keep TileSizeUU within defined bounds */
float GetClampedTileSizeUU(const float InTileSizeUU, const float CellSize, const float AgentRadius)
{
const float MinTileSize = FMath::Max3(RECAST_MIN_TILE_SIZE, CellSize * ArbitraryMinTileSizeVoxels, AgentRadius * ArbitraryMinTileSizeAgentRadius);
const float MaxTileSize = FMath::Max(RECAST_MIN_TILE_SIZE, CellSize * ArbitraryMaxTileSizeVoxels);
return FMath::Clamp<float>(InTileSizeUU, MinTileSize, MaxTileSize);
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:425
Scope (from outer to inner):
file
function FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties
Source code excerpt:
{
TilePoolSize = 1024;
TileSizeUU = 988.f;
CellSize = 19;
CellHeight = 10;
AgentRadius = 34.f;
AgentHeight = 144.f;
AgentMaxSlope = 44.f;
AgentMaxStepHeight = 35.f;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:456
Scope (from outer to inner):
file
function FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties
Source code excerpt:
{
TilePoolSize = RecastNavMesh.TilePoolSize;
TileSizeUU = RecastNavMesh.TileSizeUU;
CellSize = RecastNavMesh.GetCellSize(ENavigationDataResolution::Default);
CellHeight = RecastNavMesh.GetCellHeight(ENavigationDataResolution::Default);
AgentRadius = RecastNavMesh.AgentRadius;
AgentHeight = RecastNavMesh.AgentHeight;
AgentMaxSlope = RecastNavMesh.AgentMaxSlope;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:706
Scope (from outer to inner):
file
function void ARecastNavMesh::PostLoad
Source code excerpt:
for (uint8 Index = 0; Index < (uint8)ENavigationDataResolution::MAX; Index++)
{
UE_CLOG(TileSizeUU < GetCellSize((ENavigationDataResolution)Index), LogNavigation, Error, TEXT("%s: TileSizeUU (%f) being less than CellSize (%f) is an invalid case and will cause navmesh generation issues.")
, *GetName(), TileSizeUU, GetCellSize((ENavigationDataResolution)Index));
}
if (!UWorld::IsPartitionedWorld(GetWorld()))
{
bIsWorldPartitioned = false;
}
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:781
Scope (from outer to inner):
file
function void ARecastNavMesh::PostInitProperties
Source code excerpt:
ARecastNavMesh* DefOb = (ARecastNavMesh*)ARecastNavMesh::StaticClass()->GetDefaultObject();
if (TileSizeUU != DefOb->TileSizeUU)
{
UE_LOG(LogNavigation, Warning, TEXT("%s param: TileSizeUU(%f) differs from config settings, forcing value %f so it can be used with voxel cache!"),
*GetNameSafe(this), TileSizeUU, DefOb->TileSizeUU);
TileSizeUU = DefOb->TileSizeUU;
}
for (int i = 0; i < (uint8)ENavigationDataResolution::MAX; ++i)
{
const float CurrentCellSize = NavMeshResolutionParams[i].CellSize;
const float DefaultObjectCellSize = DefOb->NavMeshResolutionParams[i].CellSize;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:1503
Scope (from outer to inner):
file
function float ARecastNavMesh::GetTileSizeUU
Source code excerpt:
{
const float DefaultCellSize = GetCellSize(ENavigationDataResolution::Default);
const float RcTileSize = FMath::TruncToFloat(TileSizeUU / DefaultCellSize);
return RcTileSize * DefaultCellSize;
}
void ARecastNavMesh::GetEdgesForPathCorridor(const TArray<NavNodeRef>* PathCorridor, TArray<FNavigationPortalEdge>* PathCorridorEdges) const
{
check(PathCorridor != NULL && PathCorridorEdges != NULL);
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:2887
Scope (from outer to inner):
file
function double ARecastNavMesh::GetWorldPartitionNavigationDataBuilderOverlap
Source code excerpt:
double ARecastNavMesh::GetWorldPartitionNavigationDataBuilderOverlap() const
{
return TileSizeUU;
}
#endif //WITH_EDITOR
void ARecastNavMesh::DetachNavMeshDataChunk(URecastNavMeshDataChunk& NavDataChunk)
{
const TArray<FNavTileRef> DetachedIndices = NavDataChunk.DetachTiles(*this);
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3226
Scope (from outer to inner):
file
function void ARecastNavMesh::PostEditChangeChainProperty
Source code excerpt:
RefCellSize = UE::NavMesh::Private::GetClampedCellSize(RefCellSize);
TileSizeUU = UE::NavMesh::Private::GetClampedTileSizeUU(TileSizeUU, RefCellSize, AgentRadius);
// Adjust tile size to be a multiple of RefCellSize
const float RefCellCount = FMath::TruncToFloat( TileSizeUU / RefCellSize);
TileSizeUU = RefCellCount * RefCellSize;
// Adjust the other cell size (find count of cells and set the size of the cell)
for (uint8 Index = 0; Index < (uint8)ENavigationDataResolution::MAX; Index++)
{
if (Index != ChangedIndex)
{
float& ResolutionCellSize = NavMeshResolutionParams[Index].CellSize;
const float ResolutionCellCount = FMath::TruncToFloat(TileSizeUU / ResolutionCellSize);
ResolutionCellSize = UE::NavMesh::Private::GetClampedCellSize(TileSizeUU / ResolutionCellCount);
}
}
PRAGMA_DISABLE_DEPRECATION_WARNINGS
// Update the deprecated CellSize to fit the default resolution CellSize
CellSize = NavMeshResolutionParams[(uint8)ENavigationDataResolution::Default].CellSize;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3298
Scope (from outer to inner):
file
function void ARecastNavMesh::PostEditChangeProperty
Source code excerpt:
if (PropName == GET_MEMBER_NAME_CHECKED(ARecastNavMesh, AgentRadius))
{
// changing AgentRadius is no longer affecting TileSizeUU since
// that's not how we use it. It's actually not really supported to
// modify AgentRadius directly on navmesh instance, since such
// a navmesh will get discarded during navmesh registration with
// the navigation system.
// @todo consider hiding it (we might already have a ticket for that).
UE_LOG(LogNavigation, Warning, TEXT("Changing AgentRadius directly on RecastNavMesh instance is unsupported. Please use Project Settings > NavigationSystem > SupportedAgents to change AgentRadius"));
}
else if (PropName == GET_MEMBER_NAME_CHECKED(ARecastNavMesh, TileSizeUU))
{
SetCellSize(ENavigationDataResolution::Default, UE::NavMesh::Private::GetClampedCellSize(GetCellSize(ENavigationDataResolution::Default)));
TileSizeUU = UE::NavMesh::Private::GetClampedTileSizeUU(TileSizeUU, GetCellSize(ENavigationDataResolution::Default), AgentRadius);
// Match cell sizes to tile size.
for (uint8 Index = 0; Index < (uint8)ENavigationDataResolution::MAX; Index++)
{
SetCellSize((ENavigationDataResolution)Index, TileSizeUU / FMath::TruncToFloat(TileSizeUU / GetCellSize((ENavigationDataResolution)Index)));
}
PRAGMA_DISABLE_DEPRECATION_WARNINGS
// Set deprecated CellSize
CellSize = GetCellSize(ENavigationDataResolution::Default);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp:3436
Scope (from outer to inner):
file
function void ARecastNavMesh::UpdateGenerationProperties
Source code excerpt:
{
TilePoolSize = GenerationProps.TilePoolSize;
TileSizeUU = GenerationProps.TileSizeUU;
CellSize = GenerationProps.CellSize;
CellHeight = GenerationProps.CellHeight;
AgentRadius = GenerationProps.AgentRadius;
AgentHeight = GenerationProps.AgentHeight;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:1678
Scope (from outer to inner):
file
function void FRecastTileGenerator::Setup
Source code excerpt:
const FVector RcNavMeshOrigin = ParentGenerator.GetRcNavMeshOrigin();
const FBox NavTotalBounds = ParentGenerator.GetTotalBounds();
const FVector::FReal TileSizeUU = TileConfig.GetTileSizeUU();
NavDataConfig = ParentGenerator.GetOwner()->GetConfig();
TileBB = CalculateTileBounds(TileX, TileY, RcNavMeshOrigin, NavTotalBounds, TileSizeUU);
if (UE::NavMesh::Private::bUseTightBoundExpansion)
{
TileBBExpandedForAgent = ParentGenerator.GrowBoundingBox(TileBB, /*bIncludeAgentHeight*/ false);
}
else
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4585
Scope (from outer to inner):
file
namespace UE::NavMesh::Private
function int32 CalculateMaxTilesCount
Source code excerpt:
{
// Keep this as an integer division to avoid imprecision between platforms and targets (since MaxTilesCount is compared with stored data).
const int64 TileSizeUU = (int64)TileSizeInWorldUnits;
const int64 XSize = (FMath::CeilToInt(RCBox.GetSize().X) / TileSizeUU) + 1;
const int64 YSize = (FMath::CeilToInt(RCBox.GetSize().Z) / TileSizeUU) + 1;
GridCellsCount += (XSize*YSize);
}
else
{
// Support old navmesh versions
int64 XSize = FMath::CeilToInt(RCBox.GetSize().X/TileSizeInWorldUnits) + 1;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4657
Scope (from outer to inner):
file
function void FRecastNavMeshGenerator::SetupTileConfig
Source code excerpt:
OutConfig.mergeRegionArea = (int32)rcSqr(DestNavMesh->MergeRegionSize / CellSize);
OutConfig.tileSize = FMath::Max(FMath::TruncToInt(DestNavMesh->TileSizeUU / CellSize), 1);
UE_CLOG(OutConfig.tileSize == 1, LogNavigation, Error, TEXT("RecastNavMesh TileSize of 1 is highly discouraged. This occurence indicates an issue with RecastNavMesh\'s generation properties (specifically TileSizeUU: %f, CellSize: %f). Please ensure their correctness.")
, DestNavMesh->TileSizeUU, CellSize);
OutConfig.regionChunkSize = FMath::Max(1, OutConfig.tileSize / FMath::Max(1, DestNavMesh->LayerChunkSplits));
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;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Private/NavMesh/RecastNavMeshGenerator.cpp:4754
Scope (from outer to inner):
file
function void FRecastNavMeshGenerator::ConfigureBuildProperties
Source code excerpt:
OutConfig.AgentIndex = NavSys ? NavSys->GetSupportedAgentIndex(DestNavMesh) : 0;
OutConfig.tileSize = FMath::Max(FMath::TruncToInt(DestNavMesh->TileSizeUU / CellSize), 1);
UE_CLOG(OutConfig.tileSize == 1, LogNavigation, Error, TEXT("RecastNavMesh TileSize of 1 is highly discouraged. This occurence indicates an issue with RecastNavMesh\'s generation properties (specifically TileSizeUU: %f, CellSize: %f). Please ensure their correctness.")
, DestNavMesh->TileSizeUU, CellSize);
OutConfig.regionChunkSize = FMath::Max(1, OutConfig.tileSize / FMath::Max(1, DestNavMesh->LayerChunkSplits));
OutConfig.TileCacheChunkSize = FMath::Max(1, OutConfig.tileSize / FMath::Max(1, DestNavMesh->RegionChunkSplits));
OutConfig.LedgeSlopeFilterMode = DestNavMesh->LedgeSlopeFilterMode;
OutConfig.regionPartitioning = DestNavMesh->LayerPartitioning;
OutConfig.TileCachePartitionType = DestNavMesh->RegionPartitioning;
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:338
Scope: file
Source code excerpt:
/** size of single tile, expressed in uu */
UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "300.0"))
float TileSizeUU;
/** horizontal size of voxelization cell */
UPROPERTY(EditAnywhere, Category = Generation, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
float CellSize;
/** vertical size of voxelization cell */
#Loc: <Workspace>/Engine/Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h:759
Scope (from outer to inner):
file
class class ARecastNavMesh : public ANavigationData
Source code excerpt:
/** size of single tile, expressed in uu */
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "300.0"))
float TileSizeUU;
/** horizontal size of voxelization cell */
UE_DEPRECATED(5.2, "Set the CellSizes for the required navmesh resolutions in NavMeshResolutionParams.")
UPROPERTY(config)
float CellSize;