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...
使用 NavigationLink
NavigationLink 用來將 NavigationRegion2D 和 NavigationRegion3D 中的導航網格多邊形,在任意距離下進行連接,以便尋路使用。
NavigationLink 也可用於考慮尋路時,經由與遊戲物件互動才能使用的移動捷徑,例如梯子、跳板或傳送門。
2D 與 3D 版本的 NavigationJumplinks 節點,分別為 NavigationLink2D 與 NavigationLink3D。
只要不同的 NavigationRegion 有重疊邊界,或其邊緣落在導航地圖的 edge_connection_margin 內,就可以直接連接其導航網格,不需要 NavigationLink。當距離過大,無法直接建立有效連接時,就需要使用 NavigationLink 來解決此問題。
請參考 使用 NavigationRegion 以深入了解導航區域的使用方法。如需了解如何連接導航網格,請參考 連接導覽網格。
NavigationLink 與 NavigationRegion 共享許多屬性,例如 navigation_layers。NavigationLink 用於在任意距離的兩個位置之間新增一條連接,而 NavigationRegion 則是透過導航網格資源,建立本地可通行區域。
NavigationLink 擁有 start_position 與 end_position,並且在啟用 bidirectional 時支援雙向通行。放置後,導航連結會在搜尋半徑內,連接最靠近 start_position 及 end_position 的導航網格多邊形,以供尋路使用。
多邊形搜尋半徑可於專案設定(ProjectSettings)中的 navigation/2d_or_3d/default_link_connection_radius 進行全域設定,或透過 NavigationServer.map_set_link_connection_radius() 函式,針對每個導航地圖(map)個別指定。
start_position 與 end_position 在編輯器內都會顯示除錯標記。箭頭指示該連結可通行的方向,位置的可見圓形顯示多邊形搜尋半徑。所有在圓形範圍內的導航網格多邊形都會被比較,選擇最近的作為邊界連結。如果搜尋半徑內找不到有效的多邊形,該導航連結將會被停用。
你可以在編輯器的 ProjectSettings,於 debug/shapes/navigation 下變更連結的除錯視覺效果。此外,也可以在編輯器 3D 檢視區的小工具功能表中控制除錯顯示的可見性。
導航連結本身不會提供任何特殊的移動行為。當代理角色(agent)抵達連結位置時,遊戲程式需自行處理對應行為(例如透過區域觸發器),並讓代理角色以適當方式通過連結並移動到另一端(例如利用傳送、動畫等)。否則代理角色將會直接沿著連結的路徑移動。這可能導致角色直接走過深淵(而非等待移動平台),或是直接穿越傳送門卻卡在牆內。
導航連結腳本範本
以下腳本示範如何使用 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);
}
}