☰
Godot NavigationAgent3D 完全指南:3D 寻路、路径跟随与 RVO 动态避障实战
2026/10/12 20:24:51 网站建设 项目流程
  • 文档
  • 教程
  • 游戏开发

【免费下载链接】godot-docs

Godot Engine official documentation

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

本篇以 Godot 官方文档仓库中的 NavigationAgent3D 类参考 为核心骨架,系统讲解 3D 导航代理的寻路(Pathfinding)、路径跟随(Path Following)与基于 RVO 的动态避障(Avoidance)三大能力,并逐一拆解其全部属性、信号与方法。读完本文,你将能够基于 NavigationAgent3D 为 Node3D / CharacterBody3D / RigidBody3D 父节点搭建一套可复用的寻路移动框架,理解每一个配置项对路径质量与避障效果的影响,并能结合 NavigationServer3D 底层 API 与 NavigationObstacle 进行深度定制。

NavigationAgent3D 是什么

NavigationAgent3D继承自Node < Object,是 Godot 导航系统中面向 3D 场景的"一站式辅助节点"。它的核心职责是:为挂载它的父节点在 3D 空间中寻路到目标位置,并在移动过程中避开静态与动态障碍物。其 2D 对应版本是NavigationAgent2D,两者 API 结构几乎一致,只是坐标维度不同。

它的核心设计要点包括:

  • 计算结果交由父节点执行:NavigationAgent3D 本身不移动任何节点,路径点与世界坐标计算结果返回给父节点后,由你自己的移动代码驱动实际运动(参见配套教程 navigation_using_navigationagents.rst)。
  • 动态障碍采用 RVO(Reciprocal Velocity Obstacles,相互速度障碍)避障:避障计算发生在物理步骤(physics step)之前,因此寻路信息可以在物理帧内安全使用。
  • 依赖导航数据:代理本身不产生导航网格,必须存在有效的导航地图(NavigationMap)与导航网格(NavigationMesh,一般由 NavigationRegion3D 提供或烘焙生成),路径查询才有意义。
  • 标注为 Experimental:类参考文档顶部明确注明 "Experimental",意味着该类的 API 在未来版本中可能被修改或移除,生产项目应留意版本升级。

注意:设置target_position之后,必须在每个物理帧调用一次get_next_path_position()来更新代理内部路径逻辑;该方法返回的向量位置应作为父节点下一步的移动目标位置。

属性全景:一张表看懂 32 个配置项

NavigationAgent3D 的全部属性、类型与默认值如下表所示(默认值来自 class_navigationagent3d.rst):

属性类型默认值用途归类
avoidance_enabledboolfalse是否启用 RVO 避障回调
avoidance_layersint(位掩码)1本代理所在的避障层
avoidance_maskint(位掩码)1本代理需要避开的避障层
avoidance_priorityfloat1.0避障优先级
debug_enabledboolfalse是否显示调试可视化
debug_path_custom_colorColorColor(1, 1, 1, 1)自定义路径调试颜色
debug_path_custom_point_sizefloat4.0自定义路径点渲染尺寸
debug_use_customboolfalse是否使用自定义调试颜色
heightfloat1.02D 避障模式下代理的垂直高度
keep_y_velocitybooltrue2D 避障后是否保留 y 轴速度
max_neighborsint10避障计算考虑的最大邻居数
max_speedfloat10.0避障允许的最大速度
navigation_layersint(位掩码)1寻路可用的导航层
neighbor_distancefloat50.0搜索其他代理的距离
path_desired_distancefloat1.0判定"到达路径点"的阈值
path_height_offsetfloat0.0路径位置 y 轴偏移
path_max_distancefloat5.0允许偏离理想路径的最大距离
path_metadata_flags位掩码7路径附带元数据开关
path_postprocessing枚举0路径后处理模式
path_return_max_lengthfloat0.0返回路径最大长度(0=不限)
path_return_max_radiusfloat0.0返回路径最大半径(0=不限)
path_search_max_distancefloat0.0寻路搜索最大距离(0=不限)
path_search_max_polygonsint4096寻路搜索最大多边形数(0=不限)
pathfinding_algorithm枚举0寻路算法
radiusfloat0.5避障代理的"身体"半径
simplify_epsilonfloat0.0路径简化量(世界单位)
simplify_pathboolfalse是否返回简化路径
target_desired_distancefloat1.0判定"到达目标"的阈值
target_positionVector3Vector3(0, 0, 0)寻路目标位置
time_horizon_agentsfloat1.0针对其他代理的避障预测时间
time_horizon_obstaclesfloat0.0针对静态障碍的避障预测时间
use_3d_avoidanceboolfalse使用 3D(xyz)还是 2D(xz)避障
velocityVector3Vector3(0, 0, 0)期望速度(交由避障模拟修正)

这些属性可以按功能分成三大组:寻路配置、路径跟随配置、避障配置,下文逐一详解。

寻路配置:控制路径如何被算出来

当设置target_position(全局坐标)后,代理会向NavigationServer3D请求一条从当前位置到目标位置的新路径。路径的"质量"与"形态"由以下属性共同决定。

navigation_layers:限定可用的导航网格

navigation_layers是一个位掩码(bitfield),决定代理在寻路时可以使用哪些导航层的导航区域(NavigationRegion)。默认值为1(仅第 1 层)。运行时修改该值会清空当前导航路径并依据新图层重新生成路径。

配套方法get_navigation_layer_value(layer_number)与set_navigation_layer_value(layer_number, value)允许以 1~32 的数字逐位读取或开关图层。这是实现"不同角色走不同区域"的关键手段——例如普通地面单位只走地面层、飞行单位额外走空中层,具体用法可参考教程 navigation_using_navigationlayers.rst。

pathfinding_algorithm:选择寻路算法

该属性决定路径查询使用哪种寻路算法。当前枚举(定义于 class_navigationpathqueryparameters3d.rst)只有一个成员:

  • PATHFINDING_ALGORITHM_ASTAR = 0:使用默认的 A* 寻路算法。默认值即此。

path_postprocessing:路径后处理

寻路算法找到的是穿过导航网格多边形的原始路径走廊(raw path corridor),后处理决定其如何被整形为最终返回的路径点序列:

  • PATH_POSTPROCESSING_CORRIDORFUNNEL = 0(默认):对原始路径走廊应用漏斗算法(funnel algorithm),得到走廊内最短路径。该模式非常依赖导航网格的多边形布局;在基于格子/瓦片的布局中,锯齿状的走廊可能产生对角线移动的"人工拐角"。
  • PATH_POSTPROCESSING_EDGECENTERED = 1:把每个路径点居中到所经过导航网格多边形边的中点。对限制单位在格子中心移动的瓦片/网格布局更友好。
  • PATH_POSTPROCESSING_NONE = 2:不做后处理,直接返回原始路径走廊。

path_metadata_flags:路径元数据开关

这是一个位掩码,决定路径点附带多少额外信息(这些信息会随waypoint_reached/link_reached信号的 details 字典传出):

  • PATH_METADATA_INCLUDE_NONE = 0:不包含任何元数据。
  • PATH_METADATA_INCLUDE_TYPES = 1:包含每个路径点经过的导航图元类型(region 区域 或 link 链接)。
  • PATH_METADATA_INCLUDE_RIDS = 2:包含路径点经过的 region/link 的RID。
  • PATH_METADATA_INCLUDE_OWNERS = 4:包含管理这些 region/link 的Object的ObjectID。
  • PATH_METADATA_INCLUDE_ALL = 7:包含全部元数据。属性默认值正是7。

警告(来自配套教程):关闭路径元数据标志会连带禁用代理上相关的信号发射。例如不包含 types 元数据时,waypoint_reached的 details 中就缺少 type 字段。

simplify_path 与 simplify_epsilon:路径简化

  • simplify_path = true时,返回的路径会移除不重要的路径点,得到一个简化版本。
  • simplify_epsilon控制简化量(世界单位)。其内部使用Ramer-Douglas-Peucker 算法的变体进行曲线点抽稀(decimation)。

路径简化对两类场景特别有价值:"转向/steering"类代理,以及在开阔场地中启用避障的代理——它可以缓解因路径点过密而导致的抖动与来回摆动问题。

path_search_max_distance 与 path_search_max_polygons:搜索预算上限

这两个属性用于限制寻路在"目标不可达或极远"时的搜索开销:

  • path_search_max_distance(默认0.0):搜索的多边形距离起点多边形超过该值(世界单位)时,寻路中止,转而返回"起点到当前已找到的最近目标多边形"的路径。
  • path_search_max_polygons(默认4096):搜索的多边形数量达到该上限时中止,行为同上。

两者取值0或负数均视为不限:此时寻路会搜索所有与起点连通的导航多边形,直到找到目标或穷尽所有选项。在大型关卡中合理设置这两个值,可以避免寻路查询吃掉过多的单帧开销(更多性能建议参见 navigation_optimizing_performance.rst)。

path_return_max_length 与 path_return_max_radius:返回路径裁剪

  • path_return_max_length(默认0.0):返回路径的最大长度(世界单位),超过即被裁剪。
  • path_return_max_radius(默认0.0):返回路径距路径起点(即第一个路径位置)的最大半径(世界单位),超出即裁剪。与长度限制相比,它允许代理在需要绕过一个拐角时多走出一段距离。
  • 注意:半径裁剪是以第一个路径位置为球心、仅针对导航网格上的实际路径点进行的球面裁剪。

路径跟随:每物理帧驱动内部路径逻辑

寻路只是第一步,真正的"走起来"依赖路径跟随。NavigationAgent3D 拥有独立的内部路径推进逻辑,驱动它的唯一入口就是get_next_path_position()。

标准调用模式

func _physics_process(delta: float) -> void: # 地图尚未同步过一次时不要查询(避免返回空路径) if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0: return # 路径已完成时尽早返回,避免原地抖动 if navigation_agent.is_navigation_finished(): return var next_path_position: Vector3 = navigation_agent.get_next_path_position() # 用自己的移动代码朝 next_path_position 移动父节点

关键要点(来自 navigation_using_navigationagents.rst):

  • 必须每物理帧调用一次get_next_path_position(),直到is_navigation_finished()返回true。
  • 到达目标或路径终点后不要再调用该函数,否则反复的路径更新会让站定的代理原地抖动。
  • 代理没有有效路径时,get_next_path_position()返回的是父节点当前位置。
  • 导航系统永远不会替你移动父节点,移动完全由你的脚本负责。
  • 代理也可以在_process中使用,但内部更新仍受限于每物理帧一次的节奏。

三个距离阈值决定"何时推进"

路径跟随的行为由三个距离属性协同控制:

  1. path_desired_distance(默认1.0):代理距下一个路径点小于该值时,内部路径索引推进到下一个路径点。设太高会跳过路径点,可能冲出导航网格;设太低会因每帧都"过冲"而陷入不断重算路径的循环。
  2. target_desired_distance(默认1.0):代理距目标小于该值时,认为目标已到达、路径结束,触发target_reached信号并结束导航。
    • 设置大于path_desired_distance:导航会在到达最后一个路径点之前提前结束。
    • 设置小于path_desired_distance:导航不会在到达最后路径点后立刻结束,可以更贴近目标;但设得过低同样会陷入重算循环。
  3. path_max_distance(默认5.0):代理因避障等原因偏离理想路径超过该距离时,触发重新规划理想路径,并发射path_changed信号。

path_height_offset:y 轴视觉偏移

path_height_offset(默认0.0)会从该代理的每个路径位置的 y 轴值中减去该偏移量。它只影响路径位置的读取层,不会改变或影响导航网格本身与寻路查询结果。官方文档明确指出:若要支持不同体型的代理,正确做法是为不同体型以不同的NavigationMesh.agent_radius烘焙导航网格并使用不同的导航地图,而不是靠 height offset 凑合。

get_current_navigation_path 与 get_current_navigation_path_index

  • get_current_navigation_path()返回从起点到终点的全局坐标路径点数组(PackedVector3Array)。它只在目标变化或需要重算时更新,不应用于直接移动——直接修改数组会破坏代理内部路径逻辑,应当始终通过get_next_path_position()驱动移动。
  • get_current_navigation_path_index()返回代理当前处在路径数组的哪个索引。
  • get_path_length()返回当前路径总长;若路径仍在计算或尚未请求,返回0.0。

路径跟随常见问题(官方文档原版要点)

  • 返回空路径:在导航地图同步之前(例如_ready()中)查询路径可能得到空结果,此时get_next_path_position()返回父节点位置,代理会认为路径已结束。解决:延迟调用或通过地图变更信号等回调等待同步完成。
  • 代理在两位置间"跳舞":通常由每帧频繁重算路径引起(如path_max_distance设得过短)。寻路要找导航网格上最近的有效点,若每帧都重算,第一个路径点会在代理前后不断切换。
  • 偶尔回溯:代理移动太快,一帧内越过path_desired_distance判定而索引未推进,导致回头走向身后的路径点。加大 desired 距离、降低速度,或改善导航网格布局(避免小区域内边过密)通常可修复。
  • 偶尔"向后看"一帧:与"跳舞"同因,加上代理正好站在网格边/边连接处时,路径点可能因精度问题略偏后方,对"即时转向朝向路径点"的代理可见。

RVO 避障:让多个代理互相让路

避障是 NavigationAgent3D 相对普通"纯寻路"方案的核心增量。其底层是RVO(相互速度障碍)模拟:避障代理在抽象空间中只是平面上的圆(2D 避障)或空三维空间中的球(3D 避障),没有导航网格或物理碰撞的任何信息(相关说明见 navigation_using_navigationagents.rst)。

避障工作流三步

  1. 开启avoidance_enabled = true:代理注册到 NavigationServer3D 的 RVO 避障回调中。注意:大量代理同时开启避障有显著性能开销,只对当前确实需要避障的代理开启。属性面板对应下图中的勾选项:

  2. 连接velocity_computed信号接收避障计算出的安全速度:

  3. 每物理帧把父节点的当前速度写入velocity属性,并改用信号回调中的safe_velocity驱动移动:

func _physics_process(delta: float) -> void: ... var next_path_position: Vector3 = navigation_agent.get_next_path_position() var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed if navigation_agent.avoidance_enabled: navigation_agent.set_velocity(new_velocity) else: _on_velocity_computed(new_velocity) func _on_velocity_computed(safe_velocity: Vector3) -> void: velocity = safe_velocity move_and_slide()

注意两点(官方文档明确强调):

  • 只有同一地图上同样注册了避障的其他代理才会被纳入避障计算。
  • 即使只用避障,也必须设置target_position;否则velocity_computed收到的safe_velocity永远是零向量。

避障在_physics_process()中设置 velocity、以velocity_computed信号回调safe_velocity的流程如下(图中为代理启用避障与信号连接的示意图):

避障相关属性逐一解读

  • radius(默认0.5):避障代理的"身体"半径——是身体本身,不是避障机动开始的距离(那是neighbor_distance的事)。注意它不影响普通寻路:要改变角色寻路半径,应使用不同NavigationMesh.agent_radius烘焙网格 + 不同导航地图。
  • height(默认1.0,仅 3D 有):2D 避障模式下代理的垂直高度。代理会忽略"当前位置+height"之上/之下的其他代理或障碍。3D 避障不使用 height,只靠半径球。
  • neighbor_distance(默认50.0):搜索其他代理的距离。调低可减少计算开销。
  • max_neighbors(默认10):半径重叠时最多考虑多少个邻居。调低可省性能,但过低会导致代理"无视"避障。
  • time_horizon_agents(默认1.0):对其他代理的速度安全预测时间(秒)。越大,代理越早对其他代理作出反应,但速度选择自由度越小;过大会显著拖慢移动。必须为正数。
  • time_horizon_obstacles(默认0.0):对静态避障障碍的速度安全预测时间(秒)。同样"越大越早反应、越小越灵活",过大拖慢移动,必须为正数。
  • max_speed(默认10.0):避障计算允许的最大速度。若父节点实际移动快于该值,safe_velocity可能不够准确而无法有效避撞。
  • use_3d_avoidance(默认false):
    • true:在 3D 中全方位(xyz)计算避障速度,适合空中、水下或太空玩法。3D 避障代理只避开同样使用 3D 避障的代理,只对基于半径的障碍作出反应,忽略基于顶点的静态障碍。
    • false:沿 x、z 轴(忽略 y 轴)做 2D 避障。2D 代理只避开 2D 代理,可对半径障碍与顶点障碍都作出反应;位于其"当前位置+height"上下的其他 2D 代理会被忽略。
    • 注意:2D 与 3D 避障运行在两套独立的避障模拟中,分属两边的代理互相不影响。
  • avoidance_layers(默认1)与avoidance_mask(默认1):类似物理层(Physics Layers)的位掩码。代理只避开"自己的 mask 某一位 与对方 avoidance_layers 某一位匹配"的避障对象。配套方法get/set_avoidance_layer_value、get/set_avoidance_mask_value支持按 1~32 逐位操作。
  • avoidance_priority(默认1.0):高优先级代理不为低优先级代理调整速度,而低优先级代理需要更多调整来躲避高优先级代理。可用于让重要 NPC 在避障模拟中"优先通行",而不必频繁改动整个图层/掩码。
  • keep_y_velocity(默认true):使用 2D 避障时,记录设定的 y 轴速度并在避障步骤后重新应用。2D 避障本身在平坦平面上模拟、没有 y 轴,此选项可缓和起伏 3D 几何体上最明显的"穿模"。
  • velocity(默认Vector3(0, 0, 0)):设置新的期望速度,避障模拟会尽量满足它,但会为避开其他代理与障碍而修正。代理被传送(teleport)到新位置时,应同时调用set_velocity_forced()重置内部模拟速度,否则旧速度残留可能让代理瞬间冲出去。

通过 NavigationServer3D 直接控制避障

官方教程也给出了不依赖节点属性、直接调用 NavigationServer3D API 的方式(navigation_using_navigationagents.rst,对应类参考 class_navigationserver3d.rst 中的agent_set_avoidance_enabled、agent_set_avoidance_callback、agent_set_use_3d_avoidance、agent_set_velocity_forced等):

extends NavigationAgent3D func _ready() -> void: var agent: RID = get_rid() # 启用避障 NavigationServer3D.agent_set_avoidance_enabled(agent, true) # 创建避障回调 NavigationServer3D.agent_set_avoidance_callback(agent, Callable(self, "_avoidance_done")) # 切换到 3D 避障 NavigationServer3D.agent_set_use_3d_avoidance(agent, true) # 关闭避障 NavigationServer3D.agent_set_avoidance_enabled(agent, false) # 删除避障回调(传入空 Callable) NavigationServer3D.agent_set_avoidance_callback(agent, Callable()) # 切回 2D 避障 NavigationServer3D.agent_set_use_3d_avoidance(agent, false)

注意:agent_set_avoidance_callback创建的回调独立于 SceneTree 状态被处理,只要代理在导航地图上且未被释放就会派发;用空Callable再次调用即可停用派发。set_velocity_forced()以指定速度替换避障模拟中的内部速度,传送后应在同一帧调用;频繁调用会让代理卡住。

配合 NavigationObstacle 使用

避障空间本身没有环境信息,NavigationObstacle3D可以补上环境约束(详见 navigation_using_navigationobstacles.rst):

  • 静态障碍:填充vertices(顶点轮廓多边形)即视为静态,是避障代理不可穿越的硬边界,类似物理碰撞但只作用于避障。静态障碍仅对 2D 避障代理生效。
  • 动态障碍:radius > 0即为动态,作为"请离我远一点"的软性对象,像避让其他代理一样避让。2D 用圆、3D 避障用球定义边界。
  • 障碍同样使用avoidance_layers位掩码:所有"自己 avoidance_mask 中某一位与该层匹配"的代理都会避让该障碍。

信号:与代理状态交互

NavigationAgent3D 共定义 6 个信号,是驱动游戏逻辑(动画、战斗、对话触发)的主要接口:

信号参数触发时机
link_reached(details)Dictionary代理进入下一个路径位置且该位置是**导航链接(NavigationLink3D)**时(距离小于path_desired_distance)
waypoint_reached(details)Dictionary代理进入下一个路径位置(距离小于path_desired_distance)时
target_reached()无代理进入目标target_desired_distance范围内时;每条已加载路径只发射一次,且在navigation_finished之前
navigation_finished()无导航结束(可达则到达目标、不可达则走完最后路径点);每条已加载路径只发射一次,且在target_reached之后
path_changed()无路径被更新:之前为空、导航地图变更、或代理偏离超过path_max_distance
velocity_computed(safe_velocity)Vector3避障速度计算完成时;只要avoidance_enabled = true且代理有导航地图,每次更新都会发射

details 字典的元数据字段

  • waypoint_reached(details)依据path_metadata_flags可能包含:position(到达路径点位置)、type(该路径点所在导航图元类型,region 或 link)、rid(所在 region/link 的 RID)、owner(管理该图元的对象)。
  • link_reached(details)在waypoint_reached基础上,因type恒为PATH_SEGMENT_TYPE_LINK(即 NavigationPathQueryResult3D 中PATH_SEGMENT_TYPE_LINK = 1),还可能包含:
    • link_entry_position:若 owner 是NavigationLink3D,为代理进入的链接端点全局位置;
    • link_exit_position:若 owner 是NavigationLink3D,为代理离开的链接端点全局位置。

递归警告(类参考原文):get_next_path_position()等若干方法可能触发新的路径计算。若在代理信号的回调(如waypoint_reached)里调用这些方法,可能造成无限递归。官方建议:在物理步骤中调用这些方法,或使用Object.call_deferred()/Object.CONNECT_DEFERRED延迟到帧末执行。

方法与状态查询:完整 API 速查

除get_next_path_position()外,常用方法如下(完整签名见 class_navigationagent3d.rst):

方法返回说明
distance_to_target()float基于代理全局位置到目标的距离;需先设target_position才准确
get_current_navigation_path()PackedVector3Array当前完整路径(全局坐标),仅供读取
get_current_navigation_path_index()int当前路径索引
get_current_navigation_result()NavigationPathQueryResult3D当前路径的完整查询结果
get_final_position()Vector3当前路径可达的最终位置(全局坐标);路径更新(path_changed)时可能变化
get_navigation_map()RID返回节点上设置的导航地图 RID;若直接用 NavigationServer API 改了代理的地图,节点不会感知,应用set_navigation_map()
get_path_length()float当前路径总长;仍在计算或未请求时为0.0
get_rid()RID本代理在 NavigationServer3D 上的 RID
is_navigation_finished()bool导航是否结束(可达则到目标、不可达则到最后一个路径点)。true后应停止调用get_next_path_position()等更新函数,避免站立抖动
is_target_reachable()boolget_final_position()是否在target_desired_distance内接近target_position
is_target_reached()bool是否已进入目标范围。目标未必总能到达,但最终位置通常可达,参见get_final_position()
set_navigation_map(navigation_map)void设置节点使用的导航地图 RID,并同步更新 NavigationServer 上的代理
set_velocity_forced(velocity)void替换避障模拟内部速度;传送后应在同一帧使用
get/set_avoidance_layer_value(layer_number)bool/void按 1~32 逐位读写avoidance_layers
get/set_avoidance_mask_value(mask_number)bool/void按 1~32 逐位读写avoidance_mask
get/set_navigation_layer_value(layer_number)bool/void按 1~32 逐位读写navigation_layers

调试可视化

  • debug_enabled = true时为该代理显示调试可视化。
  • debug_use_custom = true时使用debug_path_custom_color(默认白色Color(1, 1, 1, 1))与debug_path_custom_point_size(默认4.0)替代全局调试颜色/点尺寸。更多导航调试工具参见 navigation_debug_tools.rst。

实战脚本模板:三种常见 3D 节点

官方教程 navigation_using_navigationagents.rst 为常见父节点提供了完整模板。以CharacterBody3D(GDScript)为例:

extends CharacterBody3D @export var movement_speed: float = 4.0 @onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D") func _ready() -> void: navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed)) func set_movement_target(movement_target: Vector3): navigation_agent.set_target_position(movement_target) func _physics_process(delta): # 地图从未同步且为空时不要查询 if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0: return if navigation_agent.is_navigation_finished(): return var next_path_position: Vector3 = navigation_agent.get_next_path_position() var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed if navigation_agent.avoidance_enabled: navigation_agent.set_velocity(new_velocity) else: _on_velocity_computed(new_velocity) func _on_velocity_computed(safe_velocity: Vector3): velocity = safe_velocity move_and_slide()

Node3D版本(无物理、直接移动)的区别在于:保存physics_delta,并在_on_velocity_computed中用global_position = global_position.move_toward(global_position + safe_velocity, physics_delta * movement_speed)移动。RigidBody3D版本则把safe_velocity赋给linear_velocity,让物理引擎接管。C# 版本在官方教程中同样齐全(VelocityComputed事件、GlobalPosition.MoveToward、MoveAndSlide()等一一对应)。

关键结论与性能提醒

  • NavigationAgent3D 是辅助节点而非必需品:其全部功能都可以用脚本 + NavigationServer3D 直接调用替代;更进阶的用法可参考 navigation_using_navigationpathqueryobjects.rst。
  • 避障不参与寻路:避障应视为"无法(重新)烘焙进导航网格的持续移动物体"的补充手段;avoidance_enabled只在确实需要时开启,否则会引入显著 CPU 开销。
  • RVO 隐含自然行为假设:它假设代理在相遇时可被分配合理的"通行侧"。因此非常刻板的避障测试场景通常会失败——例如两个代理以完美相反的速度正对相向而行,会因无法分配通行侧而卡住。
  • 每个代理配置独立的寻路/避障参数:不同体型、不同通行权限的角色,应结合导航层、不同 agent_radius 烘焙的导航网格与独立导航地图来区分,而不是依赖单一属性硬凑。

相关阅读:Using NavigationAgents 教程、NavigationServer3D 类参考、NavigationObstacle3D、NavigationPathQueryParameters3D 枚举、Navigation 教程总览。

  • 文档
  • 教程
  • 游戏开发

【免费下载链接】godot-docs

Godot Engine official documentation

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询