RigidBody3D
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — RigidBody3D
RigidBody3D
节点继承关系
继承链:Node → Node3D → PhysicsBody3D → RigidBody3D
继承自 PhysicsBody3D
| 类型 | 名称 | 说明 |
|---|---|---|
| 方法 | MoveAndCollide() | 移动并检测碰撞 |
| 方法 | TestMove() | 测试移动是否会碰撞(不实际移动) |
继承自 Node3D
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Position | 本地位置(X / Y / Z) |
| 属性 | GlobalPosition | 全局位置 |
| 属性 | Rotation | 旋转角度(欧拉角,弧度) |
| 属性 | Scale | 缩放比例 |
| 属性 | TopLevel | 是否脱离父节点的变换 |
| 方法 | LookAt() | 朝向目标点 |
| 方法 | ToGlobal() | 本地坐标转全局坐标 |
| 方法 | ToLocal() | 全局坐标转本地坐标 |
| 方法 | RotateX/Y/Z() | 绕指定轴旋转 |
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
受 3D 物理引擎完全控制的物体——你给它一个力,引擎就帮你算出它该怎么飞、怎么转、怎么弹。
RigidBody3D 和 RigidBody2D 的原理完全一样,区别在于维度。在 3D 中,物体可以在 X/Y/Z 三个轴上旋转,物理模拟更加真实。
使用频率:★★★ 一般常用——常用于 3D 游戏中需要真实物理效果的物体。
节点用途
- 可推动的箱子、桶
- 球体弹跳
- 投掷物(手雷、石头)
- 碎片、掉落物
- 任何需要真实物理效果(弹跳、旋转)的 3D 物体
使用场景
典型场景
- 3D 推箱子谜题:玩家推动箱子到指定位置
- 物理碎片:物体被击碎后的碎片散落
- 弹球/弹珠:球在 3D 空间中弹跳
不适用场景
- 需要自己精确控制移动的角色 → 使用 CharacterBody3D
- 永远不动的墙壁 → 使用 StaticBody3D
常用节点搭配
| 搭配节点 | 用途 | 必需? |
|---|---|---|
| CollisionShape3D | 定义物体的碰撞边界 | 必需 |
| MeshInstance3D | 显示物体的 3D 模型 | 推荐 |
典型节点树:
PushableBox (RigidBody3D)
├── CollisionShape3D
└── MeshInstance3D生效必备素材/资源
| 资源 | 类型 | 说明 |
|---|---|---|
| 碰撞形状(如 BoxShape3D) | Shape3D 资源 | 赋给 CollisionShape3D 子节点 |
节点属性与信号
物理参数
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
Mass | float | 1.0 | — | 质量,影响受力后的加速度 |
GravityScale | float | 1.0 | — | 重力倍数:0 = 不受重力,2 = 双倍重力 |
LinearVelocity | Vector3 | (0, 0, 0) | — | 线速度(直线移动的速度) |
AngularVelocity | Vector3 | (0, 0, 0) | — | 角速度(X/Y/Z 三个轴的旋转速度) |
LinearDamp | float | 0.0 | — | 线性阻尼(空气摩擦) |
AngularDamp | float | 0.0 | — | 角度阻尼(旋转摩擦) |
Bounce | float | 0.0 | — | 弹性系数:0 = 不弹,1 = 完美弹跳 |
Friction | float | 1.0 | — | 摩擦系数:0 = 像冰面一样滑 |
碰撞检测
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
ContactMonitor | bool | false | — | 是否监测碰撞(开启后才能接收碰撞信号) |
MaxContactsReported | int | 0 | — | 最大报告碰撞数 |
CanSleep | bool | true | — | 物体静止时是否"休眠"以节省性能 |
物理材质(Physics Material)覆盖
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
PhysicsMaterialOverride | PhysicsMaterial | null | — | 自定义物理材质 |
信号
| 信号 | 触发时机 | 继承自 | 说明 |
|---|---|---|---|
body_entered(body) | 有物理体碰到它 | PhysicsBody3D | 需开启 ContactMonitor |
body_exited(body) | 有物理体离开它 | PhysicsBody3D | 需开启 ContactMonitor |
body_shape_entered(body_rid, body, body_shape_index, local_shape_index) | 碰撞形状进入 | PhysicsBody3D | 需开启 ContactMonitor |
sleeping_state_changed() | 物体进入/退出休眠 | RigidBody3D | — |
常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
ApplyForce(force) | void | 施加持续力 |
ApplyImpulse(impulse) | void | 施加瞬间冲量 |
ApplyTorque(torque) | void | 施加旋转力矩 |
ApplyTorqueImpulse(impulse) | void | 施加瞬间旋转冲量 |
ApplyCentralForce(force) | void | 施加中心力(不会引起旋转) |
ApplyCentralImpulse(impulse) | void | 施加中心瞬间冲量 |
ApplyForceAtPosition(force, position) | void | 在指定位置施加力(会引起旋转) |
ApplyImpulseAtPosition(impulse, position) | void | 在指定位置施加冲量 |
SetAxisVelocity(axisVelocity) | void | 设置某个轴方向的速度 |
GetCollidingBodies() | GodotArray[Node] | 获取所有碰撞的物体列表 |
代码示例
C
using Godot;
/// <summary>
/// 3D 可推动的箱子
/// 节点结构:PushableBox (RigidBody3D) + MeshInstance3D + CollisionShape3D
/// </summary>
public partial class PushableBox3D : RigidBody3D
{
[Export] public float ExPushForce = 10.0f;
public void OnBodyEntered(Node body)
{
if (body is CharacterBody3D player)
{
Vector3 direction = (GlobalPosition - player.GlobalPosition).Normalized();
// 只在水平方向施加推力,不让箱子飞起来
direction.Y = 0f;
ApplyCentralImpulse(direction * ExPushForce);
}
}
}
/// <summary>
/// 3D 投掷物(如石头)
/// 节点结构:ThrownRock (RigidBody3D) + MeshInstance3D + CollisionShape3D
/// </summary>
public partial class ThrownRock : RigidBody3D
{
[Export] public float ExThrowForce = 20.0f;
[Export] public float ExLifetime = 5.0f;
private Timer _lifetimeTimer;
public override void _Ready()
{
_lifetimeTimer = new Timer();
_lifetimeTimer.WaitTime = ExLifetime;
_lifetimeTimer.OneShot = true;
_lifetimeTimer.Timeout += () => QueueFree();
AddChild(_lifetimeTimer);
}
public void Throw(Vector3 direction)
{
ApplyCentralImpulse(direction * ExThrowForce);
_lifetimeTimer.Start();
}
}GDScript
# 3D 可推动的箱子
# 节点结构:PushableBox (RigidBody3D) + MeshInstance3D + CollisionShape3D
extends RigidBody3D
@export var push_force: float = 10.0
func _on_body_entered(body: Node) -> void:
if body is CharacterBody3D:
var direction := (global_position - body.global_position).normalized()
# 只在水平方向施加推力,不让箱子飞起来
direction.y = 0.0
apply_central_impulse(direction * push_force)不要直接改 RigidBody3D 的位置!
和 2D 版本一样,Position 和 GlobalPosition 由物理引擎控制。直接修改会导致"瞬移"、"穿墙"、"抖动"等问题。
想移动 RigidBody3D?请使用 ApplyForce()、ApplyImpulse() 或直接修改 LinearVelocity。
