关于 godot-2d-physics
面向 Godot 开发者的 2D 物理技能指南,涵盖碰撞、触发器、射线检测及高性能场景。通过按工作流分流脚本并强调常见陷阱,帮助选择合适的实现方式。
主要功能
- 01碰撞层与遮罩配置
- 02射线和形状查询指导
- 03AOE 与命中检测方案
- 04大规模物理对象处理
- 05刚体安全修改与抖动修复
适用场景
- 01配置角色、敌人与地形的碰撞过滤
- 02实现视线检测、点击选择或即时命中
- 03构建近战范围或范围攻击检测
- 04处理大量子弹并排查物理抖动
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-2d-physics安装后在 Claude Code 中输入/godot-2d-physics确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/area2d-and-queries.mdcollision-layers-masks.mdmigration-notes.mdscripts/collision_bitmask_helper.gdcollision_debouncer.gdcollision_layer_matrix_manager.gdcollision_setup.gdcollision_visual_debugger.gdcompound_body_sync.gdcontinuous_collision_detection.gdcustom_gravity_area.gdcustom_gravity_override.gdcustom_physics_2d.gdcustom_physics.gdjitter_interpolation_fix.gdmove_and_collide_precision.gdperformance_batch_mover.gdphysics_direct_query.gdphysics_direct_space_query.gdphysics_interpolation_smoothing.gdphysics_queries.gdphysics_query_cache.gdphysics_server_direct_body.gdphysics_server_swarm.gdraycast_hit_prediction.gdraycast_vision_stack.gdsafe_rigidbody_state.gdshapecast_aoe_detection.gdshapecast_aoe.gdsubstepping_logic.gd详细介绍
2D 物理
关于 Godot 2D 中碰撞检测、触发器和射线检测的专业指南。
绝对不要
- 绝对不要缩放
CollisionShape2D节点——使用编辑器中的形状控制柄,而不是 Node2D 的缩放属性。缩放会导致不可预测的物理行为和错误的碰撞法线 [12]。 - 绝对不要混淆
collision_layer和collision_mask——层 =“我是什么?”,掩码 =“我会检测什么?”。通常不应将两者设为相同的值 [13]。 - 使用
move_and_slide()时,绝对不要将速度乘以 delta——move_and_slide()会自动纳入时间步长。只有重力和加速度需要乘以 delta [14]。 - 绝对不要忘记在手动进行帧中射线检测时调用
force_raycast_update()——射线检测每个物理帧更新一次。如果更改了 target_position,就必须强制更新 [15]。 - 绝对不要每帧调用
get_overlapping_bodies()——这会带来较大开销。使用body_entered/body_exited信号缓存结果 [16]。 - 绝对不要在
_process中直接修改RigidBody2D状态——使用_integrate_forces(),以安全、同步地访问PhysicsDirectBodyState2D[17, 411]。 - 绝对不要在
_process()中移动PhysicsBody2D节点——应使用_physics_process()。在物理步之外移动刚体会导致卡顿和不可靠的碰撞检测。 - 绝对不要将
RigidBody2D用于 1000 个以上的简单实体——使用PhysicsServer2D绕过节点开销,大幅提升性能(群体/子弹)[18, 397]。 - 绝对不要将
Area2D用于高频阻挡检测(子弹)——Area 信号可能会延迟。要获得帧级精度的结果,请使用move_and_collide()或ShapeCast2D[19]。 - 绝对不要忽略高刷新率显示器上的“物理抖动”——启用物理插值,防止运动时出现微小卡顿 [21, 400]。
- 绝对不要在运行时直接缩放碰撞形状——这会导致严重的不稳定。应调整形状资源的大小/半径。
- 绝对不要将
set_deferred用于需要立即生效的物理变换逻辑——它会在帧末执行。请改用force_raycast_update()或PhysicsServer2D。 - 绝对不要为慢速物体启用连续碰撞检测(CCD)——这会显著增加 CPU 开销。仅为高速投射物启用,以防止穿透。
- 绝对不要让所有瓦片/实体共用一个碰撞层——应分开设置不同层(地面、墙壁、敌人),以便通过掩码进行选择性过滤。
- 绝对不要忘记手动释放
PhysicsServer2DRID——它们不会被垃圾回收,可能导致永久性内存泄漏。
可用脚本
强制要求:编码前,请先阅读与当前工作流分支匹配的脚本。查询/Area 食谱示例位于脚本中,而非本文。
工作流路由器(必须遵循 / 请勿加载)
| 分支 | 加载 | 请勿加载 |
|---|---|---|
| 图层/遮罩矩阵设置 | collision_bitmask_helper.gd 或 collision_setup.gd;矩阵策略 → collision_layer_matrix_manager.gd | Swarm / CCD 脚本 |
| 视线 / 视锥 | raycast_vision_stack.gd(无节点射线还需 physics_direct_query.gd) | shapecast_aoe*.gd、physics_server_swarm.gd |
| AOE / 近战体积 | 优先使用 shapecast_aoe.gd(阵营遮罩);地面/体积感知 → shapecast_aoe_detection.gd | 大量使用 Area2D + 熔岩 DoT 教程;同一功能不要同时加载两个 shapecast 脚本 |
| Hitscan / 点选 / 单次形状查询 | physics_queries.gd(规范方案)。专用方案:physics_direct_space_query.gd(视线布尔值)、raycast_hit_prediction.gd | 一次性重新加载全部三个查询辅助脚本 |
| 弹幕地狱 / 1000+ 个刚体 | 必须使用 physics_server_swarm.gd(RID 形状还需 physics_server_direct_body.gd) | 每颗子弹都创建 Area2D / RigidBody2D 节点 |
| 高速穿透 | continuous_collision_detection.gd + substepping_logic.gd | 对慢速道具启用 CCD |
| 安全修改 RigidBody | safe_rigidbody_state.gd(_integrate_forces) | 在 _process 中直接写入变换 |
| 自定义 CharacterBody 力 | custom_physics_2d.gd | custom_physics.gd(该文件用于 RigidBody 的 _integrate_forces) |
| 重力区域 | custom_gravity_area.gd(Area 覆盖)或 custom_gravity_override.gd(角色重量/区域) | 除非需要 Area + 角色路径,否则不要同时使用 |
| 重叠信号过多 | collision_debouncer.gd | 每帧轮询 get_overlapping_bodies |
| 复合多形状 RID | compound_body_sync.gd | 为一个逻辑刚体创建多个节点 |
| 调试接触法线 | collision_visual_debugger.gd | 可见碰撞菜单无法满足需求 |
| 高刷新率抖动 | 优先使用 jitter_interpolation_fix.gd | physics_interpolation_smoothing.gd(旧版/手动方案;仅在内置插值不可用时使用) |
| 精确反弹 / 滑动 | move_and_collide_precision.gd | — |
| 批量静态移动物体 | performance_batch_mover.gd | — |
| 查询结果缓存 | physics_query_cache.gd | 同一帧内重复进行空间查询 |
规范方案与重叠方案(去重指南)
- ShapeCast AOE:战斗 AOE 使用
shapecast_aoe.gd;仅在进行落地/体积检测时使用shapecast_aoe_detection.gd——同一功能切勿同时使用两者。 - 空间查询:从
physics_queries.gd开始;只有在适用专用方案时才添加physics_direct_query.gd/physics_direct_space_query.gd。 - 自定义物理:CharacterBody →
custom_physics_2d.gd;RigidBody 集成 →custom_physics.gd。 - 插值:优先使用
jitter_interpolation_fix.gd,而不是physics_interpolation_smoothing.gd。
脚本索引
- collision_setup.gd / collision_bitmask_helper.gd / collision_layer_matrix_manager.gd
- physics_queries.gd / physics_direct_query.gd / physics_direct_space_query.gd / physics_query_cache.gd
- raycast_vision_stack.gd / raycast_hit_prediction.gd
- shapecast_aoe.gd / shapecast_aoe_detection.gd
- physics_server_swarm.gd / physics_server_direct_body.gd
- continuous_collision_detection.gd / substepping_logic.gd
- safe_rigidbody_state.gd / custom_physics.gd / custom_physics_2d.gd
- custom_gravity_area.gd / custom_gravity_override.gd
- collision_debouncer.gd / jitter_interpolation_fix.gd
- compound_body_sync.gd / collision_visual_debugger.gd
- move_and_collide_precision.gd / performance_batch_mover.gd
- physics_interpolation_smoothing.gd — 旧版;建议优先使用抖动修复脚本
决策树:碰撞检测方法
| 用例 | 方法 | 原因 / 脚本 |
|---|---|---|
| 持续触发区域 | Area2D + 信号 | 记录区域内的对象;使用 collision_debouncer.gd 消抖 |
| 一次性拾取物 | Area2D + 进入时调用 queue_free | 简单清理 |
| 视线检测 | RayCast2D / 直接射线 | raycast_vision_stack.gd 或 physics_direct_query.gd |
| 点击选择 | PhysicsPointQueryParameters2D | physics_queries.gd |
| AOE 法术 / 近战范围 | ShapeCast2D / 形状查询 | shapecast_aoe.gd(没有 Area 信号延迟) |
| 瞬时命中武器 | PhysicsRayQueryParameters2D | physics_queries.gd / raycast_hit_prediction.gd |
| 平台游戏地面 / 悬崖边缘 | 向下射线或 ShapeCast | CharacterBody 技能 + shapecast_aoe_detection.gd |
| 1000+ 个投射物 | PhysicsServer2D RIDs | 必须使用 physics_server_swarm.gd |
心智模型(简明)
- Layer = 我是谁;Mask = 我检测谁。位掩码指南 → collision-layers-masks.md。
- 含多个形状的 Area2D 会对每个形状分别触发一次
body_entered—— 使用 Set/dict 或 collision_debouncer.gd 去重。 - 在帧中途更改射线 / 形状需要调用
force_raycast_update()/force_shapecast_update()。 _ready中的物理查询在一个物理帧结束前会返回 false(await get_tree().physics_frame)。CharacterBody2D的默认collision_layer = 0—— 设置图层后 Area 才能检测到它。- 请自行释放 PhysicsServer RID —— 它们不会被垃圾回收。
深入指南(按需查阅)
| 主题 | 参考资料 / 脚本 |
|---|---|
| Layer/Mask 模式 | collision-layers-masks.md |
| Area2D、射线检测、形状查询 | area2d-and-queries.md |
| 复合 RID 刚体 | compound_body_sync.gd |
| 接触法线调试绘制 | collision_visual_debugger.gd |
参考
渐进式披露:仅在研究特定 API 时打开官方文档链接; 将工作交给相关领域时再加载相关技能——不要预先加载整个技能网络。
官方文档
- 物理简介 — 碰撞层与碰撞遮罩、物体类型,以及每种 2D 设置都依赖的基本概念。
- 碰撞形状(2D) — 如何正确设置形状大小,以及缩放
CollisionShape2D节点为何会破坏法线和接触。 - 使用 CharacterBody2D —
move_and_slide/move_and_collide、地面检测和运动学移动约定。 - 使用 Area2D — 触发器监测、重叠信号,以及区域的空间/重力覆盖。
- 射线投射 —
RayCast2D与PhysicsDirectSpaceState2D射线的区别、排除项,以及帧中途的force_raycast_update。 - RigidBody — 通过
_integrate_forces/PhysicsDirectBodyState2D安全地控制刚体,而不是在_process中与求解器对抗。 - 物理问题排查 — 隧穿、抖动、单向平台,以及常见的层/遮罩配置错误。
- 物理插值简介 — 固定物理帧率为何会在高刷新率显示器上导致卡顿,以及插值何时能解决问题。
- PhysicsServer2D — 基于 RID 的物体/形状 API,可在不产生 SceneTree 开销的情况下实现大规模群体 2D 物理。
- PhysicsDirectSpaceState2D — 用于视线检测、范围效果和点击拾取的点、射线及形状查询,无需永久查询节点。
- ShapeCast2D — 当无法接受
Area2D信号延迟时,用于帧精准近战/范围效果检测的体积投射。
相关技能
前置条件
- godot-project-foundations — 必须先设置项目设置中的层名称、物理帧率和默认重力,才能保证层/遮罩矩阵正常。
- godot-gdscript-mastery — 位掩码枚举、用于重叠集合的类型化字典,以及对
_physics_process的规范使用,是此处所有模式的基础。 - godot-signal-architecture —
body_entered/body_exited的连接和防抖模式需要清晰的信号所有权,才能避免信号泛滥。
互补技能
- godot-characterbody-2d — 土狼时间、跳跃缓冲和单向平台,都建立在此技能定义的碰撞约定之上。
- godot-raycasting-queries — 当视觉/射线检测系统超出基础需求时,提供更深入的查询参数配置示例(排除项、遮罩、形状投射)。
- godot-tilemap-mastery — 瓦片物理层和单向瓦片碰撞必须与刚体和区域使用的同一层矩阵保持一致。
- godot-input-handling — 物理帧输入采样以及垂直同步/延迟的选择,与
move_and_slide的手感密切相关。 - godot-physics-3d — 移植或跨维度共享层策略时,可参考并行的 3D 刚体/查询概念。
- godot-performance-optimization — 当
PhysicsServer2D中的大量对象或查询缓存成为瓶颈时,提供性能分析和批处理指导。 - godot-debugging-profiling — 诊断抖动或漏检时,可查看可视化碰撞形状、接触法线和帧耗时问题。
下游/使用方
- godot-combat-system — 攻击箱/受击箱由
Area2D与层/遮罩组合而成;伤害时机受重叠检测和 CCD 选择影响。 - godot-genre-platformer — 平台游戏的手感(地面、边缘、单向平台)依赖此领域提供的 CharacterBody2D 和碰撞设置。
- godot-navigation-pathfinding — Agent 仍需要物理层来处理阻挡物和视线检测;请确保导航网格与碰撞世界保持一致。
- godot-monte-carlo-balancer — 跳跃窗口、弹丸速度/CCD、重力和攻击箱大小都会直接改变胜率和难度曲线;应模拟这些物理参数,而非凭猜测调整。
主技能
- godot-master — 用于发现 2D 物理及相关领域的库路由器和镜像入口。
评论
支持 Markdown