某个地形中有多个地块时,它们可能会重叠,至少边缘会重叠。重叠可能会影响其中一个或全部两个地块的导航区域。
为确保 NavData 正确反映加载到内存中的几何体,NavData 生成系统会标识这些重叠区域,并对其进行特殊处理。
每个地块都需要配置由 KyGuid 类实例表示的全局唯一 ID,该 ID 在创建地块时提供。
例如,假设一个地块包含一片比较平坦的平原,相邻地块包含一座山丘。这两个地块中的几何体稍稍重叠,这样,一部分山丘落在平原上,一部分平原延伸到山丘下。
仅加载平原的 NavData 时,其 NavData 将反映平坦的地形。仅加载山丘时,其 NavData 将仅反映山坡。同时加载两个地块时,平原与山丘重叠的部分将自动替换为表示重叠区域的备用块,从而允许人物从一个地块传递到下一个地块。
此过程是完全透明的。您只需在 NavData 生成系统的同一次运行中提供所有不同的地块;将自动处理重叠数据的生成和运行时缝合。
自动重叠检测和缝合系统旨在无缝处理每个地块组合,以确保 NavMesh 始终与几何体保持一致,不管当前在游戏中加载的是哪一组地块,即使在地块之间的边界沿线也是如此。
但是,在某些情景中,您可能希望阻止生成重叠数据,以减少地块 NavData 的内存使用量。下面介绍了通常可以禁止生成重叠数据但不影响 NavMesh 精度的情景。
有时,地形几何体在游戏过程中可能会发生重大更改,此时您可能希望为两种不同状态下的该地块生成 NavData,并在地形状态发生更改的情况时在运行时进行交换。相似地块的经典示例是包含可能会在运行时遭到销毁的大型建筑的区域。当该建筑存在时,您希望地面上的角色围绕该建筑行走,您可能还希望这些角色能够在该建筑内(如在屋顶上等)移动。但是,当该建筑遭到销毁后,这些角色应自由地在以前由该建筑占用的区域的地面上穿行。
通过为几何体的每种状态设置不同的地块,并与您世界中的其余地块一起同时生成这两个地块,您可以为这两个相似地块透明地创建 NavData。例如,可以创建一个包含建筑完好无损的地形几何体的地块,以及一个包含建筑遭到破坏后的地形几何体的地块。Generator 将透明地为两个可交换地块版本创建 NavData,并创建将两个版本链接到周围地块的重叠数据。
但是,默认情况下,NavData 生成系统认为可将两个可交换地块版本同时流入内存。它将检测到这两个地块在空间上重叠,因此除创建每个地块自身的 NavMesh 外,还会为几何体组合创建覆盖整个可交换地块区域的重叠数据。这不是问题,因为系统仍将在运行时平稳工作:不管何时加载哪个地块,您都将始终具有正确表示地形的 NavMesh。但是,如果是可交换地块,那么永远不需要重叠数据,因为永远不会同时加载两个相似地块版本。因此,您可以通过一开始就阻止 NavData 生成系统创建重叠数据来节省内存。
您可以通知 Generator 永远不会同时加载哪些地块,方法是在调用 GeneratorInputOutput::AddExclusiveGuids() 时提供这些地块的 KyGuid。Generator 将不会为该地块组合生成任何重叠数据。可以根据需要多次调用该方法,以设置不同的排他地块集。
某些游戏项目使用流化子关卡,其范围遵循每个单元格具有一致长度和宽度的常规轴对齐栅格。如果您的项目使用这样的栅格在相邻的子关卡之间布置分段,则可以使用单元格框来定义地块的范围,以避免生成不必要的重叠数据。
在此方法中,将 NavData 生成框架内部使用的单元格大小与栅格单元格的大小对齐。对于每个地块,提供定义哪些单元格将被指定给该地块的框范围。
请注意,由于每个 NavData 单元格始终反映所有重叠几何体的组合,但每个单元格仅存储在一个地块中,因此,如果您仅将一个重叠地块的地形网格加载到游戏中,可能会看到 NavData 与重叠区域中的几何体之间存在局限性不一致。
有关代码示例,请参见 Tutorial_Generation_cellbox.cpp 文件。