Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Использование NavigationLinks
NavigationLinks используются для соединения полигонов навигационной сетки из NavigationRegion2D и NavigationRegion3D на произвольных расстояниях для поиска пути.
NavigationLinks также используются для учета сокращенных путей перемещения при поиске пути посредством взаимодействия с игровыми объектами, например, лестницами, трамплинами или телепортами.
2D- и 3D-версии узлов NavigationJumplinks доступны как NavigationLink2D и NavigationLink3D соответственно.
Различные навигационные области могут соединять свои навигационные сетки без использования NavigationLink, если у них есть пересекающиеся рёбра или рёбра, находящиеся в пределах edge_connection_margin навигационной карты. Как только расстояние становится слишком большим, построение корректных соединений становится проблемой, которую могут решить NavigationLinks.
Подробнее об использовании навигационных регионов см. в документе Использование NavigationRegions. Подробнее о соединении навигационных сеток см. в документе Подключение навигационных сеток.
Элементы NavigationLinks имеют много общих свойств с NavigationRegions, например, navigation_layers. NavigationLinks добавляют единую связь между двумя точками на произвольном расстоянии в отличие от NavigationRegions, которые добавляют более локальную проходимую область с ресурсом навигационной сетки.
У NavigationLinks есть start_position и end_position, и они могут идти в обоих направлениях, если включено bidirection. При размещении навигационная ссылка соединяет полигоны навигационной сетки, ближайшие к ее start_position и end_position в пределах радиуса поиска пути.
Радиус поиска полигона можно настроить глобально в ProjectSettings в разделе navigation/2d_or_3d/default_link_connection_radius или задать для каждой навигационной карты индивидуально с помощью функции NavigationServer.map_set_link_connection_radius().
В редакторе есть отладочные маркеры для start_position и end_position. Стрелки указывают направление, в котором можно перемещаться по ссылке, а видимый радиус позиции показывает радиус поиска полигонов. Все полигоны навигационной сетки внутри сравниваются, и для соединения с ребром выбирается ближайший из них. Если в радиусе поиска не найдено ни одного подходящего полигона, навигационная ссылка отключается.
Визуальные элементы отладки ссылок можно изменить в редакторе ProjectSettings в разделе debug/shapes/navigation. Видимость отладки также можно контролировать в меню гизмо редактора 3D Viewport.
Навигационная ссылка не обеспечивает какого-либо специального перемещения по ней. Вместо этого, когда агент достигает точки ссылки, игровой код должен отреагировать (например, через триггеры области) и предоставить агенту возможность пройти по ссылке, чтобы оказаться в другой точке ссылки (например, посредством телепортации или анимации). Без этого агент будет пытаться двигаться по пути ссылки самостоятельно. В итоге получится, что агент идёт по бездонной яме вместо того, чтобы дождаться движущейся платформы, или проходит через телепорт и проходит сквозь стену.
Шаблоны сценариев навигационных ссылок
Следующий скрипт использует NavigationServer для создания новой навигационной ссылки.
extends Node2D
var link_rid: RID
var link_start_position: Vector2
var link_end_position: Vector2
func _ready() -> void:
link_rid = NavigationServer2D.link_create()
var link_owner_id: int = get_instance_id()
var link_enter_cost: float = 1.0
var link_travel_cost: float = 1.0
var link_navigation_layers: int = 1
var link_bidirectional: bool = true
NavigationServer2D.link_set_owner_id(link_rid, link_owner_id)
NavigationServer2D.link_set_enter_cost(link_rid, link_enter_cost)
NavigationServer2D.link_set_travel_cost(link_rid, link_travel_cost)
NavigationServer2D.link_set_navigation_layers(link_rid, link_navigation_layers)
NavigationServer2D.link_set_bidirectional(link_rid, link_bidirectional)
# Enable the link and set it to the default navigation map.
NavigationServer2D.link_set_enabled(link_rid, true)
NavigationServer2D.link_set_map(link_rid, get_world_2d().get_navigation_map())
# Move the 2 link positions to their intended global positions.
NavigationServer2D.link_set_start_position(link_rid, link_start_position)
NavigationServer2D.link_set_end_position(link_rid, link_end_position)
using Godot;
public partial class MyNode2D : Node2D
{
private Rid _linkRid;
private Vector2 _linkStartPosition;
private Vector2 _linkEndPosition;
public override void _Ready()
{
_linkRid = NavigationServer2D.LinkCreate();
ulong linkOwnerId = GetInstanceId();
float linkEnterCost = 1.0f;
float linkTravelCost = 1.0f;
uint linkNavigationLayers = 1;
bool linkBidirectional = true;
NavigationServer2D.LinkSetOwnerId(_linkRid, linkOwnerId);
NavigationServer2D.LinkSetEnterCost(_linkRid, linkEnterCost);
NavigationServer2D.LinkSetTravelCost(_linkRid, linkTravelCost);
NavigationServer2D.LinkSetNavigationLayers(_linkRid, linkNavigationLayers);
NavigationServer2D.LinkSetBidirectional(_linkRid, linkBidirectional);
// Enable the link and set it to the default navigation map.
NavigationServer2D.LinkSetEnabled(_linkRid, true);
NavigationServer2D.LinkSetMap(_linkRid, GetWorld2D().NavigationMap);
// Move the 2 link positions to their intended global positions.
NavigationServer2D.LinkSetStartPosition(_linkRid, _linkStartPosition);
NavigationServer2D.LinkSetEndPosition(_linkRid, _linkEndPosition);
}
}
extends Node3D
var link_rid: RID
var link_start_position: Vector3
var link_end_position: Vector3
func _ready() -> void:
link_rid = NavigationServer3D.link_create()
var link_owner_id: int = get_instance_id()
var link_enter_cost: float = 1.0
var link_travel_cost: float = 1.0
var link_navigation_layers: int = 1
var link_bidirectional: bool = true
NavigationServer3D.link_set_owner_id(link_rid, link_owner_id)
NavigationServer3D.link_set_enter_cost(link_rid, link_enter_cost)
NavigationServer3D.link_set_travel_cost(link_rid, link_travel_cost)
NavigationServer3D.link_set_navigation_layers(link_rid, link_navigation_layers)
NavigationServer3D.link_set_bidirectional(link_rid, link_bidirectional)
# Enable the link and set it to the default navigation map.
NavigationServer3D.link_set_enabled(link_rid, true)
NavigationServer3D.link_set_map(link_rid, get_world_3d().get_navigation_map())
# Move the 2 link positions to their intended global positions.
NavigationServer3D.link_set_start_position(link_rid, link_start_position)
NavigationServer3D.link_set_end_position(link_rid, link_end_position)
using Godot;
public partial class MyNode3D : Node3D
{
private Rid _linkRid;
private Vector3 _linkStartPosition;
private Vector3 _linkEndPosition;
public override void _Ready()
{
_linkRid = NavigationServer3D.LinkCreate();
ulong linkOwnerId = GetInstanceId();
float linkEnterCost = 1.0f;
float linkTravelCost = 1.0f;
uint linkNavigationLayers = 1;
bool linkBidirectional = true;
NavigationServer3D.LinkSetOwnerId(_linkRid, linkOwnerId);
NavigationServer3D.LinkSetEnterCost(_linkRid, linkEnterCost);
NavigationServer3D.LinkSetTravelCost(_linkRid, linkTravelCost);
NavigationServer3D.LinkSetNavigationLayers(_linkRid, linkNavigationLayers);
NavigationServer3D.LinkSetBidirectional(_linkRid, linkBidirectional);
// Enable the link and set it to the default navigation map.
NavigationServer3D.LinkSetEnabled(_linkRid, true);
NavigationServer3D.LinkSetMap(_linkRid, GetWorld3D().NavigationMap);
// Move the 2 link positions to their intended global positions.
NavigationServer3D.LinkSetStartPosition(_linkRid, _linkStartPosition);
NavigationServer3D.LinkSetEndPosition(_linkRid, _linkEndPosition);
}
}