最后同步日期:2026-04-15 | Godot 官方原文 — GPUParticlesCollision3D 系列
继承链:Node → Node3D → GPUParticlesCollision3D
| 类型 | 名称 | 说明 |
|---|
| 属性 | Position | 本地位置(X / Y / Z) |
| 属性 | GlobalPosition | 全局位置 |
| 属性 | Rotation | 旋转角度(欧拉角,弧度) |
| 属性 | Scale | 缩放比例 |
| 属性 | TopLevel | 是否脱离父节点的变换 |
| 方法 | LookAt() | 朝向目标点 |
| 方法 | ToGlobal() | 本地坐标转全局坐标 |
| 方法 | ToLocal() | 全局坐标转本地坐标 |
| 方法 | RotateX/Y/Z() | 绕指定轴旋转 |
| 类型 | 名称 | 说明 |
|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
粒子碰撞体(Collision Shape)——定义一个 3D 区域,GPU 粒子飞到这个区域时会像碰到墙一样反弹、停止或消失。让粒子能和场景产生真实的互动。
打个比方:没有碰撞体时,粒子像幽灵一样穿过墙壁和地板,很不真实。加上碰撞体后,粒子就像小弹珠一样,碰到墙壁会反弹,碰到地板会堆积。
GPUParticlesCollision3D 系列包括:
- GPUParticlesCollisionBox3D:方形碰撞区域
- GPUParticlesCollisionSphere3D:球形碰撞区域
- GPUParticlesCollisionHeightField3D:高度场碰撞,适合地形
- GPUParticlesCollisionSDF3D:基于 SDF(有符号距离场)的碰撞,最精确但最耗性能
使用频率:★★ 偶尔使用——需要让粒子与场景产生物理交互时使用。
- 让粒子碰到地面后堆积(如雪堆积在地面上)
- 让粒子碰到墙壁后反弹(如弹珠效果)
- 让粒子碰到物体后消失(如火焰碰到水面熄灭)
- 让粒子沿着地形表面流动(如水流沿着山坡流下)
- 雪地效果:雪花落到地面后堆积
- 水花效果:水粒子碰到岩石后四散
- 火焰碰到水:火焰粒子碰到水面后消失
- 粒子沿地形流动:水流沿着山坡流下
- 粒子不需要和场景交互 → 不需要碰撞体
- 2D 游戏 → 不支持
典型节点树:
SnowScene (Node3D)
├── GPUParticles3D ← 雪花粒子
├── GPUParticlesCollisionHeightField3D ← 地形碰撞(雪花落在地形上)
└── Ground (MeshInstance3D) ← 地面
| 资源 | 类型 | 说明 |
|---|
| HeightMap(高度场碰撞用) | Texture2D | 赋给 GPUParticlesCollisionHeightField3D 的 heightmap 属性 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
cull_mask | int | 0xFFFFFFFF | — | 碰撞遮罩,决定影响哪些粒子系统 |
attraction | float | 0.0 | — | 吸引力。粒子靠近碰撞面时是否被吸引 |
attraction_acceleration | float | 0.0 | — | 吸引加速的加速度 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
size | Vector3 | (2, 2, 2) | — | 方形碰撞区域的大小 |
friction | float | 0.1 | — | 摩擦力。粒子碰到表面后的减速程度 |
bounce | float | 0.5 | — | 弹性。0 = 不弹,1 = 完美反弹 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
radius | float | 1.0 | — | 球形碰撞区域的半径 |
friction | float | 0.1 | — | 摩擦力 |
bounce | float | 0.5 | — | 弹性 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
resolution | int | 64 | — | 高度场分辨率 |
size | Vector3 | (10, 2, 10) | — | 高度场覆盖范围 |
heightmap | Texture2D | — | — | 高度贴图,定义地形的起伏 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
size | Vector3 | (2, 2, 2) | — | SDF 体积大小 |
resolution | int | 32 | — | SDF 分辨率 |
friction | float | 0.1 | — | 摩擦力 |
bounce | float | 0.5 | — | 弹性 |
| 信号 | 触发时机 | 继承自 | 说明 |
|---|
| 无自有信号 | — | — | GPUParticlesCollision3D 自身不发出信号 |
C
using Godot;
/// <summary>
/// 雪花效果系统
/// 雪花从天空飘落,碰到地面后堆积
/// </summary>
public partial class SnowEffect : Node3D
{
private GPUParticles3D _snow;
private GPUParticlesCollisionHeightField3D _groundCollision;
public override void _Ready()
{
// 创建雪花粒子
_snow = new GPUParticles3D
{
Amount = 500,
Lifetime = 5.0f,
ProcessMaterial = CreateSnowMaterial()
};
_snow.Position = new Vector3(0, 20f, 0);
AddChild(_snow);
// 创建地面碰撞(高度场)
_groundCollision = new GPUParticlesCollisionHeightField3D
{
Size = new Vector3(100f, 5f, 100f),
Friction = 0.8f, // 高摩擦力,雪花落地后很快停止
Bounce = 0.0f // 不弹跳
};
AddChild(_groundCollision);
}
private ParticleProcessMaterial CreateSnowMaterial()
{
var mat = new ParticleProcessMaterial();
mat.Direction = new Vector3(0, -1, 0);
mat.Spread = 15f;
mat.Gravity = new Vector3(0, -1f, 0); // 轻微下落
mat.InitialVelocityMin = 0.5f;
mat.InitialVelocityMax = 1.5f;
mat.TurbulenceEnabled = true; // 开启湍流,让雪花飘来飘去
mat.TurbulenceStrengthMin = 0.5f;
mat.TurbulenceStrengthMax = 1.0f;
return mat;
}
}
GDScript
## 雪花效果系统
## 雪花从天空飘落,碰到地面后堆积
extends Node3D
var snow: GPUParticles3D
var ground_collision: GPUParticlesCollisionHeightField3D
func _ready():
# 创建雪花粒子
snow = GPUParticles3D.new()
snow.amount = 500
snow.lifetime = 5.0
snow.position = Vector3(0, 20.0, 0)
snow.process_material = _create_snow_material()
add_child(snow)
# 创建地面碰撞(高度场)
ground_collision = GPUParticlesCollisionHeightField3D.new()
ground_collision.size = Vector3(100.0, 5.0, 100.0)
ground_collision.friction = 0.8 # 高摩擦力,雪花落地后很快停止
ground_collision.bounce = 0.0 # 不弹跳
add_child(ground_collision)
func _create_snow_material() -> ParticleProcessMaterial:
var mat := ParticleProcessMaterial.new()
mat.direction = Vector3(0, -1, 0)
mat.spread = 15.0
mat.gravity = Vector3(0, -1.0, 0) # 轻微下落
mat.initial_velocity_min = 0.5
mat.initial_velocity_max = 1.5
mat.turbulence_enabled = true # 开启湍流,让雪花飘来飘去
mat.turbulence_strength_min = 0.5
mat.turbulence_strength_max = 1.0
return mat
碰撞体类型选择
- Box3D / Sphere3D:简单形状碰撞,性能最好,适合简单的碰撞区域
- HeightField3D:高度场碰撞,适合地形起伏较大的场景
- SDF3D:最精确的碰撞,能匹配复杂形状,但性能消耗最大
- 一般情况下优先用 Box3D 或 Sphere3D,只有确实需要精确碰撞时才用 SDF3D
bounce = 0 让粒子碰到表面后停止,bounce = 1 让粒子完美反弹friction 控制粒子碰到表面后的减速程度