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...
使用 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 additionalheight
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)