使用 NavigationLayer
NavigationLayers 是一项可选功能,用于进一步控制在路径查询中考虑哪些导航网格。它们的工作原理类似于物理层如何控制碰撞对象之间的碰撞,或视觉层如何控制渲染到视口的内容。
NavigationLayers可以在 ProjectSettings 中与物理层或视觉层相同地命名。

如果一个区域没有一个与路径查询的 navigation_layers
参数兼容的导览层,则在寻路时将跳过该区域的导览网格。有关查询导览服务器路径的更多信息,请参阅 使用 NavigationPath 。
NavigationLayers是用作 bitmask 的单个 int
值。许多与导航相关的节点都具有 set_navigation_layer_value()
和 get_navigation_layer_value()
函数,可以直接设置和获取层数,而不需要更复杂的逐位操作。
在脚本中,以下辅助函数可用于处理 navigation_layers
位掩码。
func change_layers():
var region: NavigationRegion2D = get_node("NavigationRegion2D")
# enables 4-th layer for this region
region.navigation_layers = enable_bitmask_inx(region.navigation_layers, 4)
# disables 1-rst layer for this region
region.navigation_layers = disable_bitmask_inx(region.navigation_layers, 1)
var agent: NavigationAgent2D = get_node("NavigationAgent2D")
# make future path queries of this agent ignore regions with 4-th layer
agent.navigation_layers = disable_bitmask_inx(agent.navigation_layers, 4)
var path_query_navigation_layers: int = 0
path_query_navigation_layers = enable_bitmask_inx(path_query_navigation_layers, 2)
# get a path that only considers 2-nd layer regions
var path: PackedVector2Array = NavigationServer2D.map_get_path(
map,
start_position,
target_position,
true,
path_query_navigation_layers
)
static func is_bitmask_inx_enabled(_bitmask: int, _index: int) -> bool:
return _bitmask & (1 << _index) != 0
static func enable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask | (1 << _index)
static func disable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask & ~(1 << _index)
using Godot;
public partial class MyNode2D : Node2D
{
private Rid _map;
private Vector2 _startPosition;
private Vector2 _targetPosition;
private void ChangeLayers()
{
NavigationRegion2D region = GetNode<NavigationRegion2D>("NavigationRegion2D");
// Enables the 4th layer for this region.
region.NavigationLayers = EnableBitmaskInx(region.NavigationLayers, 4);
// Disables the 1st layer for this region.
region.NavigationLayers = DisableBitmaskInx(region.NavigationLayers, 1);
NavigationAgent2D agent = GetNode<NavigationAgent2D>("NavigationAgent2D");
// Make future path queries of this agent ignore regions with the 4th layer.
agent.NavigationLayers = DisableBitmaskInx(agent.NavigationLayers, 4);
uint pathQueryNavigationLayers = 0;
pathQueryNavigationLayers = EnableBitmaskInx(pathQueryNavigationLayers, 2);
// Get a path that only considers 2nd layer regions.
Vector2[] path = NavigationServer2D.MapGetPath(
_map,
_startPosition,
_targetPosition,
true,
pathQueryNavigationLayers
);
}
private static bool IsBitmaskInxEnabled(uint bitmask, int index)
{
return (bitmask & (1 << index)) != 0;
}
private static uint EnableBitmaskInx(uint bitmask, int index)
{
return bitmask | (1u << index);
}
private static uint DisableBitmaskInx(uint bitmask, int index)
{
return bitmask & ~(1u << index);
}
}
func change_layers():
var region: NavigationRegion3D = get_node("NavigationRegion3D")
# enables 4-th layer for this region
region.navigation_layers = enable_bitmask_inx(region.navigation_layers, 4)
# disables 1-rst layer for this region
region.navigation_layers = disable_bitmask_inx(region.navigation_layers, 1)
var agent: NavigationAgent3D = get_node("NavigationAgent3D")
# make future path queries of this agent ignore regions with 4-th layer
agent.navigation_layers = disable_bitmask_inx(agent.navigation_layers, 4)
var path_query_navigation_layers: int = 0
path_query_navigation_layers = enable_bitmask_inx(path_query_navigation_layers, 2)
# get a path that only considers 2-nd layer regions
var path: PackedVector3Array = NavigationServer3D.map_get_path(
map,
start_position,
target_position,
true,
path_query_navigation_layers
)
static func is_bitmask_inx_enabled(_bitmask: int, _index: int) -> bool:
return _bitmask & (1 << _index) != 0
static func enable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask | (1 << _index)
static func disable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask & ~(1 << _index)
using Godot;
public partial class MyNode3D : Node3D
{
private Rid _map;
private Vector3 _startPosition;
private Vector3 _targetPosition;
private void ChangeLayers()
{
NavigationRegion3D region = GetNode<NavigationRegion3D>("NavigationRegion3D");
// Enables the 4th layer for this region.
region.NavigationLayers = EnableBitmaskInx(region.NavigationLayers, 4);
// Disables the 1st layer for this region.
region.NavigationLayers = DisableBitmaskInx(region.NavigationLayers, 1);
NavigationAgent3D agent = GetNode<NavigationAgent3D>("NavigationAgent2D");
// Make future path queries of this agent ignore regions with the 4th layer.
agent.NavigationLayers = DisableBitmaskInx(agent.NavigationLayers, 4);
uint pathQueryNavigationLayers = 0;
pathQueryNavigationLayers = EnableBitmaskInx(pathQueryNavigationLayers, 2);
// Get a path that only considers 2nd layer regions.
Vector3[] path = NavigationServer3D.MapGetPath(
_map,
_startPosition,
_targetPosition,
true,
pathQueryNavigationLayers
);
}
private static bool IsBitmaskInxEnabled(uint bitmask, int index)
{
return (bitmask & (1 << index)) != 0;
}
private static uint EnableBitmaskInx(uint bitmask, int index)
{
return bitmask | (1u << index);
}
private static uint DisableBitmaskInx(uint bitmask, int index)
{
return bitmask & ~(1u << index);
}
}
查询路径时更改导航层在性能上优于开关整个导航区块。与变动整个导航区块相比,使用不同的导航层进行路径查询并不会导致 NavigationServer 发生大面积更新。
更改 NavigationAgent 节点的导航层将立即影响下一次路径查询。更改区域的导航层将在下一次 NavigationServer 同步后生效。