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.

使用 NavigationObstacle

NavigationObstacles can be used either as static or dynamic obstacles to affect avoidance controlled agents.

  • When used statically NavigationObstacles constrain avoidance controlled agents outside or inside a polygon defined area.

  • When used dynamically NavigationObstacles push away avoidance controlled agents in a radius around them.

2D and 3D versions of NavigationObstacles nodes are available as NavigationObstacle2D and NavigationObstacle3D respectively.


NavigationObstacles do not change or influence the pathfinding in any way. NavigationObstacles only affect the avoidance velocities of agents controlled by avoidance.


A NavigationObstacle is considered static when its vertices property is populated with an outline array of positions to form a polygon.

  • Static obstacles act as hard do-not-cross boundaries for avoidance using agents, e.g. similar to physics collision but for avoidance.

  • Static obstacles define their boundaries with an array of outline vertices (positions), and in case of 3D with an additional height property.

  • Static obstacles only work for agents that use the 2D avoidance mode.

  • Static obstacles define through winding order of the vertices if agents are pushed out or sucked in.

  • Static obstacles can not change their position. They can only be warped to a new position and rebuild from scratch. Static obstacles as a result are ill-suited for usages where the position is changed every frame as the constant rebuild has a high performance cost.

  • Static obstacles that are warped to another position can not be predicted by agents. This creates the risk of getting agents stuck should a static obstacle be warped on top of agents.

When the 2D avoidance is used in 3D the y-axis of Vector3 vertices is ignored. Instead, the global y-axis position of the obstacle is used as the elevation level. Agents will ignore static obstacles in 3D that are below or above them. This is automatically determined by global y-axis position of both obstacle and agent as the elevation level as well as their respective height properties.


NavigationObstacle 的 radius 属性大于零时就会被认为是动态障碍物。

  • 对于启用了避障的代理而言,动态障碍物就是一个“请离我远点”的对象,类似于它们自己躲避其他代理的行为。

  • 动态障碍物使用 radius 半径来定义边界,2D 中是圆形,3D 中是球形。

  • 动态障碍物每一帧都可以改变位置,不会有额外的性能开销。

  • 动态障碍物设置速度后,其他代理就能够预测移动。

  • 动态障碍物不适合用来将代理限制在拥挤、狭窄的空间中。


和代理类似,障碍物也能够使用 avoidance_layers 位掩码。自身的避障掩码中与之存在匹配位的代理都会躲避这个障碍物。


可以不借助节点,直接在 NavigationServer 上新建障碍物。

使用脚本创建的障碍物至少需要有一个 map 和一个 position。动态障碍物还需要 radius。静态障碍物还需要 vertices 属性。

# For 2D

# create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer2D.obstacle_create()
var default_2d_map_rid: RID = get_world_2d().get_navigation_map()

NavigationServer2D.obstacle_set_map(new_obstacle_rid, default_2d_map_rid)
NavigationServer2D.obstacle_set_position(new_obstacle_rid, global_position)

# Use obstacle dynamic by increasing radius above zero.
NavigationServer2D.obstacle_set_radius(new_obstacle_rid, 5.0)

# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector2Array([Vector2(-100, -100), Vector2(100, -100), Vector2(100, 100), Vector2(-100, 100)])
NavigationServer2D.obstacle_set_vertices(new_obstacle_rid, outline)

# Enable the obstacle.
NavigationServer2D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)
# For 3D

# Create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer3D.obstacle_create()
var default_3d_map_rid: RID = get_world_3d().get_navigation_map()

NavigationServer3D.obstacle_set_map(new_obstacle_rid, default_3d_map_rid)
NavigationServer3D.obstacle_set_position(new_obstacle_rid, global_position)

# Use obstacle dynamic by increasing radius above zero.
NavigationServer3D.obstacle_set_radius(new_obstacle_rid, 0.5)

# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector3Array([Vector3(-5, 0, -5), Vector3(5, 0, -5), Vector3(5, 0, 5), Vector3(-5, 0, 5)])
NavigationServer3D.obstacle_set_vertices(new_obstacle_rid, outline)
# Set the obstacle height on the y-axis.
NavigationServer3D.obstacle_set_height(new_obstacle_rid, 1.0)

# Enable the obstacle.
NavigationServer3D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)