Navmesh bounds are too large 报错修复方法

当地图相当大,在生成导航时会有以下提示:
enter image description here
LogNavigation: Error: Navmesh bounds are too large! Limiting requested tiles count (5472000) to: (1048576) for RecastNavMesh /Game/Level/Map.Map:PersistentLevel.RecastNavMesh-Default<br>

这是因为地图太大,超出了 Tile 的数量限制。
引擎中默认 Tile 的最大数量为 1<<20 也就是 1048576=2^10,这个值可以修改配置,但不能大于 1<<30 = 1073741824 = 2^30(因为它用 int32 存储)。
Source/Runtime/NavigationSystem/Public/NavMesh/RecastNavMesh.h

UCLASS(config=Engine, defaultconfig, hidecategories=(Input,Rendering,Tags,"Utilities|Transformation",Actor,Layers,Replication), notplaceable)
class NAVIGATIONSYSTEM_API ARecastNavMesh : public ANavigationData
{
  // ...
  /** Absolute hard limit to number of navmesh tiles. Be very, very careful while modifying it while
   *  having big maps with navmesh. A single, empty tile takes 176 bytes and empty tiles are
   *  allocated up front (subject to change, but that's where it's at now)
   *  @note TileNumberHardLimit is always rounded up to the closest power of 2 */
  UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1", UIMin = "1"), AdvancedDisplay)
  int32 TileNumberHardLimit;
    // ...
};

以及使用:
Runtime/NavigationSystem/Private/NavMesh/RecastNavMesh.cpp

FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties()
{
  TilePoolSize = 1024;
  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;
  MaxSimplificationError = 1.3f;  // from RecastDemo
  TileNumberHardLimit = 1 << 20;
  RegionPartitioning = ERecastPartitioning::Watershed;
  LayerPartitioning = ERecastPartitioning::Watershed;
  RegionChunkSplits = 2;
  LayerChunkSplits = 2;
  bSortNavigationAreasByCost = false;
  bPerformVoxelFiltering = true;
  bMarkLowHeightAreas = false;
  bUseExtraTopCellWhenMarkingAreas = true;
  bFilterLowSpanSequences = false;
  bFilterLowSpanFromTileCache = false;
  bFixedTilePoolSize = false;
}

FRecastNavMeshGenerationProperties::FRecastNavMeshGenerationProperties(const ARecastNavMesh&amp; RecastNavMesh)
{
  TilePoolSize = RecastNavMesh.TilePoolSize;
  TileSizeUU = RecastNavMesh.TileSizeUU;
  CellSize = RecastNavMesh.CellSize;
  CellHeight = RecastNavMesh.CellHeight;
  AgentRadius = RecastNavMesh.AgentRadius;
  AgentHeight = RecastNavMesh.AgentHeight;
  AgentMaxSlope = RecastNavMesh.AgentMaxSlope;
  AgentMaxStepHeight = RecastNavMesh.AgentMaxStepHeight;
  MinRegionArea = RecastNavMesh.MinRegionArea;
  MergeRegionSize = RecastNavMesh.MergeRegionSize;
  MaxSimplificationError = RecastNavMesh.MaxSimplificationError;
  TileNumberHardLimit = RecastNavMesh.TileNumberHardLimit;
  RegionPartitioning = RecastNavMesh.RegionPartitioning;
  LayerPartitioning = RecastNavMesh.LayerPartitioning;
  RegionChunkSplits = RecastNavMesh.RegionChunkSplits;
  LayerChunkSplits = RecastNavMesh.LayerChunkSplits;
  bSortNavigationAreasByCost = RecastNavMesh.bSortNavigationAreasByCost;
  bPerformVoxelFiltering = RecastNavMesh.bPerformVoxelFiltering;
  bMarkLowHeightAreas = RecastNavMesh.bMarkLowHeightAreas;
  bUseExtraTopCellWhenMarkingAreas = RecastNavMesh.bUseExtraTopCellWhenMarkingAreas;
  bFilterLowSpanSequences = RecastNavMesh.bFilterLowSpanSequences;
  bFilterLowSpanFromTileCache = RecastNavMesh.bFilterLowSpanFromTileCache;
  bFixedTilePoolSize = RecastNavMesh.bFixedTilePoolSize;
}
ARecastNavMesh::ARecastNavMesh(const FObjectInitializer&amp; ObjectInitializer)
  : Super(ObjectInitializer)
  , bDrawFilledPolys(true)
  , bDrawNavMeshEdges(true)
  , bDrawNavLinks(true)
  , bDrawOctreeDetails(true)
  , bDrawMarkedForbiddenPolys(false)
  , bDistinctlyDrawTilesBeingBuilt(true)
  , DrawOffset(10.f)
  , TilePoolSize(1024)
  , MaxSimplificationError(1.3f)  // from RecastDemo
  , DefaultMaxSearchNodes(RECAST_MAX_SEARCH_NODES)
  , DefaultMaxHierarchicalSearchNodes(RECAST_MAX_SEARCH_NODES)
  , bPerformVoxelFiltering(true)  
  , bMarkLowHeightAreas(false)
  , bUseExtraTopCellWhenMarkingAreas(true)
  , bFilterLowSpanSequences(false)
  , bFilterLowSpanFromTileCache(false)
  , bStoreEmptyTileLayers(false)
  , bUseVirtualFilters(true)
  , bAllowNavLinkAsPathEnd(false)
  , TileSetUpdateInterval(1.0f)
  , NavMeshVersion(NAVMESHVER_LATEST) 
  , RecastNavMeshImpl(NULL)
{
  HeuristicScale = 0.999f;
  RegionPartitioning = ERecastPartitioning::Watershed;
  LayerPartitioning = ERecastPartitioning::Watershed;
  RegionChunkSplits = 2;
  LayerChunkSplits = 2;
  MaxSimultaneousTileGenerationJobsCount = 1024;
  bDoFullyAsyncNavDataGathering = false;
  TileNumberHardLimit = 1 << 20;

#if RECAST_ASYNC_REBUILDING
  BatchQueryCounter = 0;
#endif // RECAST_ASYNC_REBUILDING


  if (HasAnyFlags(RF_ClassDefaultObject) == false)
  {
    INC_DWORD_STAT_BY(STAT_NavigationMemory, sizeof(*this) );

    FindPathImplementation = FindPath;
    FindHierarchicalPathImplementation = FindPath;

    TestPathImplementation = TestPath;
    TestHierarchicalPathImplementation = TestHierarchicalPath;

    RaycastImplementation = NavMeshRaycast;

    RecastNavMeshImpl = new FPImplRecastNavMesh(this);

    // add predefined areas up front
    SupportedAreas.Add(FSupportedAreaData(UNavArea_Null::StaticClass(), RECAST_NULL_AREA));
    SupportedAreas.Add(FSupportedAreaData(UNavArea_LowHeight::StaticClass(), RECAST_LOW_AREA));
    SupportedAreas.Add(FSupportedAreaData(UNavArea_Default::StaticClass(), RECAST_DEFAULT_AREA));
  }
}

修复方法一

TileNumberHardLimit 的值可以通过配置文件进行设置:可以给一个比较大的TileNumberHardLimit来解决
DefaultEngine.ini

[/Script/NavigationSystem.RecastNavMesh]
bDrawPolyEdges=False
bDistinctlyDrawTilesBeingBuilt=True
DrawOffset=10.000000
bFixedTilePoolSize=False
TilePoolSize=1024
TileSizeUU=1000.000000
CellSize=19.000000
CellHeight=10.000000
AgentRadius=34.000000
AgentHeight=144.000000
AgentMaxHeight=160.000000
AgentMaxSlope=44.000000
AgentMaxStepHeight=35.000000
MinRegionArea=0.000000
MergeRegionSize=400.000000
MaxSimplificationError=1.300000
MaxSimultaneousTileGenerationJobsCount=1024
TileNumberHardLimit=1048576
DefaultDrawDistance=5000.000000
DefaultMaxSearchNodes=2048.000000
DefaultMaxHierarchicalSearchNodes=2048.000000
RegionPartitioning=Watershed
LayerPartitioning=Watershed
RegionChunkSplits=2
LayerChunkSplits=2
bSortNavigationAreasByCost=False
bPerformVoxelFiltering=True
bMarkLowHeightAreas=False
bDoFullyAsyncNavDataGathering=False
bUseBetterOffsetsFromCorners=True
bUseVirtualFilters=True
bUseVoxelCache=False
TileSetUpdateInterval=1.000000
HeuristicScale=0.999000
VerticalDeviationFromGroundCompensation=0.000000
bForceRebuildOnLoad=True

修复方法二

由于tile的数量,是由NavmeshBoundsVolume除以RecasterNavMesh的体积获得.
可以根据游戏实际情况缩小navmesh的采样空间,或者增加RecasterNavMesh的采样粒度,从而减少tiles的数量.

相关文章

关闭
星空