一句话区分
Area2D 是“传感器”,只负责感知;PhysicsBody2D 是“实体”,真正参与物理碰撞。 物体会直接穿过 Area2D,但会被 PhysicsBody2D 挡住。
Area2D:只“看”,不“撞”
Area2D 本身不是一个物体,只是一块无形的检测范围。它不受重力、不被推动,也不阻挡任何东西——别的物体会毫无阻碍地穿过它。它做的事只有一件:当有东西进入或离开这片区域时,发出信号。
func : # 典型用法:金币被玩家拾取
body.:
典型用途:
- 拾取物(金币、道具)
- 触发器(陷阱、剧情触发、传送门)
- 敌人的视野/侦测范围、伤害判定区域(AOE)
- 改变区域内的物理环境:Area2D 有一个 space override 功能,可以覆盖进入者的重力方向/大小和阻尼——比如做“水域”,让 RigidBody2D 进水后下沉变慢。
两个关键属性:monitoring(我是否检测别人)和 monitorable(我能否被别的 Area 检测到)。检测规则就是上一轮说的单向判定:(目标的 layer & Area 的 mask) != 0。
PhysicsBody2D:真正“撞”的东西
这是一个抽象基类,实际使用的是它的三个子类,区别在于“谁来控制它的运动”:
- StaticBody2D —— 完全不动。墙、地面、平台。质量相当于无限大,别人撞它会被弹开,它自己永远不动。
- RigidBody2D —— 完全交给物理引擎。你不能直接设置它的位置,只能施力、给冲量;它会受重力、会旋转、会弹跳、会堆叠。适合箱子、球、掉落的碎片等“物理道具”。
- CharacterBody2D —— 完全由你写代码控制。玩家和 NPC 用它:自己调用
move_and_slide()移动,会被墙挡住、能站在地上,但不会被物理模拟推来推去,也不会自动旋转。它是 3.x 时代 KinematicBody2D 的继任者。 - (4.x 还有 AnimatableBody2D:跟 AnimationPlayer 动画同步移动的平台等。)
对比总结
| Area2D | PhysicsBody2D 系列 | |
|---|---|---|
| 本质 | 检测区域(传感器) | 物理实体 |
| 阻挡其他物体 | 否,直接穿过 | 是 |
| 受重力/力 | 否 | 是(CharacterBody 的移动由代码手动控制) |
| 核心机制 | body_entered / body_exited / area_entered 信号 | 物理碰撞解算 + move_and_slide() 等 |
| 特殊能力 | 覆盖区域内的重力/阻尼 | 摩擦、弹性等材质属性 |
选型口诀:
- 想知道“有东西进来了” → Area2D
- 想挡住别人 → StaticBody2D
- 想让物理引擎替你驱动它(掉落、弹跳、堆叠)→ RigidBody2D
- 想自己写移动逻辑的角色 → CharacterBody2D
两个常见注意点:① 无论哪种,都必须挂 CollisionShape2D(或 CollisionPolygon2D)才算真正生效;② 金币、子弹这类“碰到就生效”的东西通常用 Area2D 而不是 RigidBody2D——你感兴趣的是“碰到了”这个事件,而不是物理反应。3D 里概念完全对应:Area3D、StaticBody3D、RigidBody3D、CharacterBody3D。