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:

  1. CellSize: TileSizeUU must be larger than CellSize.
  2. 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:

  1. TileSizeUU has a minimum value constraint (300.0 units).
  2. It affects performance and memory usage; larger tiles consume more memory but may reduce the number of tiles needed.
  3. Changing TileSizeUU requires regeneration of the navigation mesh.
  4. It’s used in various calculations, including area measurements and time estimations for navigation mesh generation.

Best practices when using TileSizeUU include:

  1. Ensure it’s set to a value that’s a multiple of the CellSize for optimal performance.
  2. Balance between memory usage and generation time when choosing a value.
  3. Consider the size of your game world and typical obstacles when setting this value.
  4. Avoid changing it frequently, as it requires full regeneration of the navigation mesh.
  5. 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]

#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;