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