NavigationObstacle2D
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — NavigationObstacle2D
NavigationObstacle2D
节点继承关系
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
NavigationObstacle2D 是一个动态障碍物——它可以在运行时移动和改变形状,让开启了避障功能的 NavigationAgent2D 自动绕开它。想象你在马路上推着一辆手推车,其他行人看到手推车后会自动绕开走——NavigationObstacle2D 就是那辆手推车。
使用频率:★★ 偶尔使用——当需要 AI 之间互相避让,或者 AI 需要躲避动态障碍物时使用
节点用途
- 作为动态障碍物,让开启避障的 Agent 自动绕开
- 支持圆形(radius)和多边形(vertices)两种形状
- 可以在运行时动态改变位置和形状
- 设置 avoidance_enabled 后,其他 Agent 会在路径规划中考虑此障碍物
使用场景
- AI 互相避让:每个 AI 角色都附带一个 NavigationObstacle2D,让它们在移动时互相避让,不会撞在一起
- 可推动的箱子:箱子附带 NavigationObstacle2D,当玩家推箱子时,AI 会自动绕开移动中的箱子
- 移动的车辆:道路上的 NPC 车辆作为障碍物,行人 AI 会自动避让
- 临时路障:在游戏中动态生成的障碍物(比如倒塌的树)
常用节点搭配
| 搭配节点 | 搭配方式 |
|---|---|
| NavigationAgent2D | Agent 开启 avoidance_enabled 后会自动绕开 Obstacle |
| NavigationRegion2D | Obstacle 放置在 Region 定义的可行走区域内 |
生效必备素材/资源
- NavigationRegion2D:Obstacle 必须在某个 Region 的范围内
- NavigationAgent2D 的 avoidance_enabled 必须为 true,否则 Agent 不会避障
节点属性与信号
属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| radius | float | 0.0 | 障碍物圆形半径。大于 0 时使用圆形碰撞,等于 0 时使用多边形碰撞 |
| vertices | PackedVector2Array | — | 多边形顶点数组,定义障碍物的形状(radius 为 0 时生效) |
| avoidance_enabled | bool | false | 是否参与避障系统。true 时其他 Agent 会在移动时考虑此障碍物 |
| avoidance_layers | int | 1 | 避障层位掩码,控制哪些 Agent 会避让此障碍物 |
| enabled | bool | true | 是否启用此障碍物 |
信号
NavigationObstacle2D 没有特有信号,继承自 Node 的通用信号。
常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
| is_enabled() | bool | 是否已启用 |
| set_enabled(enabled) | void | 设置是否启用 |
| get_radius() | float | 获取圆形半径 |
| set_radius(radius) | void | 设置圆形半径 |
| get_vertices() | PackedVector2Array | 获取多边形顶点 |
| set_vertices(vertices) | void | 设置多边形顶点 |
| set_avoidance_enabled(enabled) | void | 设置是否参与避障 |
代码示例
创建动态移动的障碍物
以下示例创建一个在两点之间来回移动的障碍物,开启避障后 AI 会自动绕开它:
C
using Godot;
public partial class MovingObstacle : Node2D
{
[Export] public float ExMoveSpeed = 80.0f;
[Export] public Vector2 ExPointA = new Vector2(100, 300);
[Export] public Vector2 ExPointB = new Vector2(400, 300);
private NavigationObstacle2D _obstacle;
private bool _movingToB = true;
public override void _Ready()
{
// 创建障碍物
_obstacle = new NavigationObstacle2D();
_obstacle.Radius = 20.0f; // 圆形障碍物,半径 20
_obstacle.AvoidanceEnabled = true; // 启用避障
_obstacle.AvoidanceLayers = 1; // 避障层 1
AddChild(_obstacle);
GlobalPosition = ExPointA;
}
public override void _PhysicsProcess(double delta)
{
// 在 A 点和 B 点之间来回移动
Vector2 target = _movingToB ? ExPointB : ExPointA;
Vector2 direction = (target - GlobalPosition).Normalized();
GlobalPosition += direction * ExMoveSpeed * (float)delta;
// 到达目标点后反向
if (GlobalPosition.DistanceTo(target) < 2.0f)
{
_movingToB = !_movingToB;
}
}
}GDScript
extends Node2D
@export var move_speed: float = 80.0
@export var point_a: Vector2 = Vector2(100, 300)
@export var point_b: Vector2 = Vector2(400, 300)
var _obstacle: NavigationObstacle2D
var _moving_to_b: bool = true
func _ready() -> void:
# 创建障碍物
_obstacle = NavigationObstacle2D.new()
_obstacle.radius = 20.0 # 圆形障碍物,半径 20
_obstacle.avoidance_enabled = true # 启用避障
_obstacle.avoidance_layers = 1 # 避障层 1
add_child(_obstacle)
global_position = point_a
func _physics_process(delta: float) -> void:
# 在 A 点和 B 点之间来回移动
var target: Vector2 = point_b if _moving_to_b else point_a
var direction: Vector2 = (target - global_position).normalized()
global_position += direction * move_speed * delta
# 到达目标点后反向
if global_position.distance_to(target) < 2.0:
_moving_to_b = not _moving_to_b