PhysicsBody2D
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — PhysicsBody2D
PhysicsBody2D
节点继承关系
继承链:Node → CanvasItem → Node2D → PhysicsBody2D
继承自 Node2D
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Position | 本地位置(相对于父节点) |
| 属性 | GlobalPosition | 全局位置 |
| 属性 | Rotation | 旋转角度(弧度) |
| 属性 | Scale | 缩放比例 |
| 属性 | Skew | 倾斜角度(弧度) |
| 方法 | Rotate() | 旋转指定弧度 |
| 方法 | ToGlobal() | 本地坐标转全局坐标 |
| 方法 | ToLocal() | 全局坐标转本地坐标 |
继承自 CanvasItem
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Visible | 是否可见 |
| 属性 | Modulate | 整体颜色叠加(乘法) |
| 属性 | SelfModulate | 自身颜色叠加(不影响子节点) |
| 属性 | ZIndex | 绘制层级(Z 轴排序) |
| 信号 | visibility_changed | 可见性变化时触发 |
| 方法 | GetGlobalMousePosition() | 获取鼠标全局坐标 |
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
所有 2D 物理体的"老祖宗"——一个抽象基类,你不能直接使用它,但所有 2D 物理体(角色、刚体、静态体、可动画体)都是从它派生出来的。
想象一棵家谱树——最上面的是老祖宗(PhysicsBody2D),下面是他的孩子们(CharacterBody2D、RigidBody2D、StaticBody2D、AnimatableBody2D)。老祖宗定义了一些所有物理体都有的共同特征(碰撞层、碰撞掩码、碰撞例外),孩子们各自又有自己的特殊能力。
使用频率:★★★★ 维度专用常用——不直接使用。这是理解物理节点继承关系的关键节点。
节点用途
- 不直接使用,作为所有 2D 物理体的基类
- 理解物理体共同属性的基础
派生节点一览
| 派生节点 | 说明 | 链接 |
|---|---|---|
| CharacterBody2D | 角色物理体——你自己控制移动 | ★★★ |
| RigidBody2D | 刚体——物理引擎控制移动 | ★★ |
| StaticBody2D | 静态体——永远不动 | ★★★ |
| AnimatableBody2D | 可动画体——动画/代码驱动移动 | ★ |
所有子类共享的属性
这些属性从 PhysicsBody2D 继承下来,所有子节点都有:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
CollisionLayer | uint | 1 | 所在碰撞层(用位掩码表示) |
CollisionMask | uint | 1 | 检测哪些碰撞层(用位掩码表示) |
CollisionPriority | float | 1.0 | 碰撞处理优先级 |
PhysicsMaterialOverride | PhysicsMaterial | null | 自定义物理材质 |
碰撞层和碰撞掩码(重要概念)
碰撞层(CollisionLayer)和碰撞掩码(CollisionMask)是 Godot 物理系统中最重要的概念之一。
打个比方:
- 碰撞层 = "我是谁"(这个物体属于哪个组)
- 碰撞掩码 = "我能碰到谁"(这个物体能和哪些组碰撞)
只有当物体 A 的碰撞层与物体 B 的碰撞掩码有重叠,且物体 B 的碰撞层与物体 A 的碰撞掩码也有重叠时,两个物体才会发生碰撞。
例如:
- 玩家的碰撞层 = 第 1 层,碰撞掩码 = 第 2 层 + 第 3 层
- 墙壁的碰撞层 = 第 2 层,碰撞掩码 = 第 1 层
- 结果:玩家碰到墙壁(第 1 层和第 2 层互相匹配)
所有子类共享的方法
| 方法 | 返回值 | 说明 |
|---|---|---|
AddCollisionExceptionWith(body) | void | 添加碰撞例外(两个物体不再碰撞) |
RemoveCollisionExceptionWith(body) | void | 移除碰撞例外 |
GetCollisionExceptions() | GodotArray[Node] | 获取碰撞例外列表 |
SetCollisionLayer(value) | void | 设置碰撞层 |
SetCollisionMask(value) | void | 设置碰撞掩码 |
GetCollisionLayer() | uint | 获取碰撞层 |
GetCollisionMask() | uint | 获取碰撞掩码 |
所有子类共享的信号
| 信号 | 触发时机 | 说明 |
|---|---|---|
body_entered(body) | 有物理体进入碰撞区域 | 需开启 ContactMonitor(仅 RigidBody2D) |
body_exited(body) | 有物理体离开碰撞区域 | 需开启 ContactMonitor |
body_shape_entered(...) | 碰撞形状进入 | 需开启 ContactMonitor |
如何选择子类?
我需要一个 2D 物理体
├── 我要自己控制它的移动(玩家、AI敌人)→ CharacterBody2D
├── 物理引擎控制它的移动(箱子、弹球) → RigidBody2D
├── 它永远不会动(地板、墙壁) → StaticBody2D
└── 通过动画/代码移动,温和推动其他物体 → AnimatableBody2D