Использование NavigationLayers
NavigationLayers — это дополнительная функция для дальнейшего управления тем, какие навигационные сетки учитываются в запросе пути. Они работают аналогично тому, как физические слои управляют столкновениями между объектами столкновения или как визуальные слои управляют тем, что отображается в Окне просмотра.
NavigationLayers можно именовать в ProjectSettings так же, как физические слои или визуальные слои.
Если в регионе нет ни одного совместимого навигационного слоя с параметром navigation_layers запроса пути, навигационная сетка этого региона будет пропущена при поиске пути. Подробнее о запросе путей к NavigationServer см. в документе Использование NavigationPaths.
NavigationLayers — это одно 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.