关于 godot-raycasting-queries
面向 Godot 开发者的物理查询技能指南,涵盖射线、形状、点位及多重命中查询。提供按需求选择查询 API 的参考脚本,并说明时机、遮罩和 RID 排除等注意事项。
主要功能
- 01PhysicsDirectSpaceState 射线查询
- 02ShapeCast 体积检测
- 03多重命中与穿透射线
- 04RID 排除与查询过滤
- 05屏幕坐标转世界射线
适用场景
- 01实现高频视线或命中扫描
- 02检测落脚点、爆炸范围或重叠对象
- 03制作穿透弹道与 3D 鼠标拾取
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-raycasting-queries安装后在 Claude Code 中输入/godot-raycasting-queries确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/migration-notes.mdquery-elite-patterns.mdscripts/direct_space_state_raycast.gdfield_of_view_scanner.gdmouse_pick_3d_query.gdmultiple_hit_piercing_ray.gdpoint_in_shape_query.gdquery_exclusion_optimization.gdraycast_reflection_logic.gdrest_info_3d_stuck_fix.gdshapecast_ground_detection.gdwater_buoyancy_surface_calc.gd详细介绍
可用脚本
常见路径的必读内容——实现前请阅读(不要凭记忆臆测查询 API):
- direct_space_state_raycast.gd — 无需 RayCast 节点即可高频调用
intersect_ray。- query_exclusion_optimization.gd — 使用 RID 排除列表,避免投射体命中自身。
- shapecast_ground_detection.gd — 当细射线穿透或漏检时,用于检测落脚点/支撑面的体积投射。
不要为一个任务加载下方所有脚本。仅打开与决策表相匹配的条目。
direct_space_state_raycast.gd
熟练使用 PhysicsDirectSpaceState2D/3D,绕过基于节点的开销,执行高频查询。
shapecast_ground_detection.gd
使用基于体积的 ShapeCast 而非细射线,可靠地检测地面/落脚点。
multiple_hit_piercing_ray.gd
实现可穿透的投射物,在单条射线上检测并返回多个命中结果。
field_of_view_scanner.gd
使用一组射线投射实现 AI 传感器逻辑,检测视野锥内的目标。
raycast_reflection_logic.gd
根据碰撞法线反射计算激光或子弹的反弹路径。
point_in_shape_query.gd
检查单个点上是否有重叠的物理实体(爆炸中心)。
rest_info_3d_stuck_fix.gd
使用 get_rest_info 检测卡住的物体并立即解决重叠。
mouse_pick_3d_query.gd
将 2D 屏幕坐标转换为 3D 世界射线,以实现点击交互。
water_buoyancy_surface_calc.gd
使用从高处向低处的射线投射,查找浮力系统所需的水面高度。
query_exclusion_optimization.gd
通过在相交检测中排除指定 RID(资源 ID)来优化性能。
物理查询中绝对不要做的事
- 绝不要在
_physics_process()之外访问direct_space_state——物理空间可能已锁定或正在单独的线程上运行;在_process()中查询并不安全 [1, 2]。 - 在细 RayCast 已足够时,绝不要使用 ShapeCast——体积查询的开销要高得多。除非需要体积检测,否则默认使用射线 [3, 4]。
- 绝不要假定结果会返回
CollisionObject节点——CSG 形状、GridMap和TileMapLayer返回的是它们自身,而非通用物理实体 [5, 6]。 - 绝不要假定 RayCast 节点会立即更新——它们每个物理帧只更新一次。如果移动节点后立即查询,必须调用
force_raycast_update()[3, 9]。 - 绝不要在物理查询中使用复杂的视觉网格——仅 GPU 上的数据需要昂贵的线程锁定才能解析。请使用简化的基本碰撞形状 [10, 11]。
- 绝不要遍历结果来查找第一个有效命中——使用
collision_mask和collision_layer在服务器层面筛选查询,以获得最高性能。 - 绝不要忘记排除投射体自身——从角色中心发出的射线会命中角色自身。使用
query.exclude = [self.get_rid()][20]。 - 绝不要使用射线检测小型、高速移动的区域——帧率下降时,射线可能会“穿透”薄墙。子弹应使用
cast_motion或高频步进。 - 绝不要在 GDScript 中逐条执行 1000 条以上的射线查询——如果查询数量极大,请批量执行查询,或直接在 C++ 中使用
PhysicsServer。 - 绝不要忽略
result.rid——RID 是在后续查询中识别和排除物体的最快方式,无需查找节点路径 [20]。
查询类型决策表
选择能够回答问题的成本最低的 API。使用射线/形状时,务必同时使用 RID 排除和掩码(query_exclusion_optimization.gd)。
| 需求 | 优先使用 | 成本 | 适用场景 | 脚本 |
|---|---|---|---|---|
| 场景中的持久传感器(边缘、瞄准辅助调试) | RayCast2D/RayCast3D 节点 | 低至中 | 射线较少;可以等待一个物理帧(或调用 force_raycast_update()) | 场景节点 + NEVER 规则 |
| 命中扫描/视线检测/帧中单次射线 | PhysicsDirectSpaceState*.intersect_ray | 低 | 高频调用,无需永久节点 | 必需 direct_space_state_raycast.gd |
| 落脚检测、厚墙、近战范围 | ShapeCast* / intersect_shape | 中至高 | 细射线会穿透或无法覆盖范围 | 必需 shapecast_ground_detection.gd |
| 爆炸/检测某点占用情况 | intersect_point | 低至中 | 获取爆炸中心的重叠列表 | point_in_shape_query.gd |
| 卡住/穿透修复 | get_rest_info | 中 | 重叠恢复 | rest_info_3d_stuck_fix.gd |
| 沿直线穿透/多次命中 | 重复调用 intersect_ray + 排除 RID | 中 | 持续飞行的弹体 | multiple_hit_piercing_ray.gd |
| 屏幕 → 世界坐标点击 | 摄像机投影 + intersect_ray | 低 | 选择对象 | mouse_pick_3d_query.gd |
3D 鼠标拾取示例
func screen_point_to_ray():
var space_state = get_world_3d().direct_space_state
var mouse_pos = get_viewport().get_mouse_position()
var origin = project_ray_origin(mouse_pos)
var end = origin + project_ray_normal(mouse_pos) * 2000
var query = PhysicsRayQueryParameters3D.create(origin, end)
var result = space_state.intersect_ray(query)
if result:
return result.collider
return null
专家说明(查询时机与视线检测)
- 仅在物理步骤中执行 — 在
_physics_process中使用direct_space_state,不要在_process中使用。 - 命中自身 — 从角色中心发射射线时,设置
query.exclude = [get_rid()]。 - NavMesh 视线检测 — 物理射线不等于 NavMesh 中的挖空区域;严格检测网格视线时,检查
NavigationServer3D.map_get_path的path.size() == 2(详见深入说明)。 - 表面类型 — 对贴花/脚步声而言,
collider.get_meta(&"surface_type")优于类/组检查。 - 计算型 GPU 射线 — 不在讨论范围内;它不能直接替代游戏逻辑中的
intersect_ray。
深入说明(按需加载)
NavMesh 视线检测验证器、表面元数据、拾取基线、穿透说明 — references/query-elite-patterns.md。
参考资料
渐进式披露:仅在研究特定 API 时打开官方文档链接; 将工作分配给相关领域的同伴时再加载相关技能 — 不要预先加载整个技能网络。
官方文档
- 射线投射 — 节点
RayCast*与PhysicsDirectSpaceState*查询、结果字典,以及用于避免命中自身的exclude。 - 物理简介 — 用于筛选物理服务器上每种射线、形状和点查询的碰撞层/遮罩。
- 碰撞形状(3D) — 为什么查询需要使用基本/凸形状而不是视觉网格,以实现可靠且开销低的相交检测。
- PhysicsDirectSpaceState3D — 用于帧中空间查询的
intersect_ray/intersect_shape/intersect_point/get_rest_info/cast_motion约定。 - PhysicsDirectSpaceState2D — 直接空间查询的 2D 对应版本,可在无需永久投射节点的情况下用于视线检测、即时射击和点状爆炸中心。
- PhysicsRayQueryParameters3D — 可复用射线参数对象的遮罩、排除 RID、
hit_from_inside和碰撞标志。 - PhysicsShapeQueryParameters3D — 用于体积投射、静止信息和卡住重叠处理的形状 RID + 变换设置。
- PhysicsPointQueryParameters3D — 用于爆炸中心和占用检查的形状内点重叠列表。
- RayCast3D — 场景树投射节点、碰撞例外,以及移动后需要调用
force_raycast_update()的情形。 - ShapeCast3D — 用于检测落脚点/近战攻击、弥补细射线遗漏的体积投射和
force_shapecast_update()。 - Camera3D — 使用活动摄像机生成从屏幕到世界的拾取射线时所用的
project_ray_origin/project_ray_normal。 - 鼠标和输入坐标 — 创建拾取射线之前,了解视口鼠标位置与画布/世界空间的区别。
相关技能
前置条件
- godot-project-foundations — 必须先设置命名物理层和 tick 设置,才能确保查询遮罩以及水面/地面层位一致。
- godot-gdscript-mastery — 类型化查询参数、RID 数组,以及仅在
_physics_process中访问空间,都是本技能依赖的语言级约定。 - godot-2d-physics — 2D 刚体/区域层矩阵,以及传感器何时应优先使用
RayCast2D节点而非直接空间状态。
补充
- godot-physics-3d — 3D 物体类型、CCD 和碰撞设置决定了射线和形状投射实际能够命中什么。
- godot-characterbody-2d — 落地、边缘和土狼时间的手感通常会用到此领域提供的 ShapeCast/射线落脚结果。
- godot-input-handling — 物理步中的点击/瞄准采样与鼠标拾取射线和命中扫描时序相关联。
- godot-navigation-pathfinding — 物理 LOS 与 NavMesh 路径直线度检查;确保障碍物挖空和碰撞世界保持一致。
- godot-ai-navigation — 视野扇形和视觉传感器会为 AI 感知系统提供输入,而这些系统仍需要正确的查询掩码/排除项。
- godot-performance-optimization — 为数百条射线分配预算、复用查询参数,并了解节点投射何时会造成 SceneTree 开销。
- godot-debugging-profiling — 可视化投射线/形状,并诊断因掩码、排除项或更新时间错误导致的漏命中。
下游/使用方
- godot-combat-system — 命中扫描、穿透射线和近战范围会根据此处产生的查询结果结算伤害。
- godot-genre-shooter — 命中扫描武器、子弹穿透和瞄准辅助会用到排除项/掩码方案以及多重命中穿透循环。
- godot-monte-carlo-balancer — 视距、视野射线数量、穿透最大命中数和查询频率会影响公平性与难度;应模拟这些参数,而不是凭猜测设定。
主索引
- godot-master — 用于发现光线投射/查询模式及相关领域的库路由器和镜像入口。