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 也可以用来实现寻路过程中需要与游戏中的对象交互才能使用的捷径,例如梯子、跳板、传送门等。
NavigationJumplink 节点的 2D 和 3D 版本分别为 NavigationLink2D 和 NavigationLink3D。
不同 NavigationRegion 的导航网格是可以相互连接的,只要这些导航网格之间存在重叠的边缘,或者距离在导航地图的 edge_connection_margin
以内,就无需借助 NavigationLink。如果距离太远就无法建立有效的连接了,NavigationLink 就可以解决这个问题。
请参阅 使用导航区块 以了解有关导航区域使用的更多信息。请参阅 连接导航网格 以了解有关如何连接导航网格的更多信息。

NavigationLinks与NavigationRegions共享许多属性,例如 navigation_layers
。与使用导览网格资源新增更多本地可走访区域的NavigationRegions相比,NavigationLink在任意距离的两个位置之间新增单一联机。
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 单独设置。
Both start_position
and end_position
have debug markers in the Editor.
The arrows indicate which direction the link can be travelled across, and the visible radius of
a position shows the polygon search radius. All navigation mesh polygons inside are compared and
the closest is picked for the edge connection. If no valid polygon is found within the search
radius the navigation link gets disabled.

可以在 debug/shapes/navigation
下的编辑器中更改链接调试视觉效果 ProjectSettings。调试的可见性也可以在编辑器3D视口小工具菜单中进行控制。
导航链接并不会提供沿链接移动的特殊移动。代理抵达链接位置时,游戏代码需要对此作出反应(例如借助区域触发器实现)并为代理提供移动到链接另一端的手段(例如传送或动画)。不作出反应的话,代理就会尝试让自己沿着连接移动,你可能就会看到代理不等可移动的平台过来就在无底洞上行走,或者越过传送门继续往墙里走。
导航链接脚本模板
以下代码使用 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);
}
}