> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/particle-system.md).

# 粒子系统

向场景添加火焰、雨、火花和魔法光环等粒子效果

粒子系统可通过发射并动画化大量小精灵来创建动态视觉效果。可用它们构建火焰、烟雾、雨、雪、火花、魔法光环、爆炸，以及许多其他用静态网格体难以实现的效果。

## 添加粒子系统

要将粒子系统添加到你的场景中，请创建一个实体并附加 `ParticleSystem` 组件。

```ts
import { engine, Transform, ParticleSystem } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'

const emitter = engine.addEntity()

Transform.create(emitter, {
	position: Vector3.create(8, 1, 8),
})

ParticleSystem.create(emitter, {})
```

未设置任何属性时，该组件使用所有默认值：一个点发射器，每秒发射 10 个粒子，粒子寿命为 5 秒。

## 发射器形状

发射器形状决定粒子从哪里生成。可通过以下 `ParticleSystem.Shape` 辅助函数提供四种形状。

### Point

粒子从单个点生成（实体的位置）。如果未指定形状，这是默认值。

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Point(),
})
```

### 球体

粒子从球体表面或内部生成。

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Sphere({ radius: 2 }),
})
```

### 锥体

粒子从锥体底部生成，并沿锥体方向向外移动。 `angle` 是半角（度）； `半径` 是底部半径（米）。要调整锥体方向，请设置实体的旋转。 `Transform`.

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Cone({ angle: 25, radius: 1 }),
})
```

### 盒体

粒子从盒体体积的任意位置生成。

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Box({ size: Vector3.create(3, 1, 3) }),
})
```

## 发射属性

控制生成多少粒子以及它们存活多久。

| 属性             | 默认     | 描述             |
| -------------- | ------ | -------------- |
| `rate`         | `10`   | 每秒发射的粒子数（持续）。  |
| `maxParticles` | `1000` | 同时存活粒子的硬上限。    |
| `lifetime`     | `5`    | 每个粒子的寿命（秒）。    |
| `active`       | `true` | 系统是否正在主动发射新粒子。 |

```ts
ParticleSystem.create(emitter, {
	rate: 50,
	maxParticles: 500,
	lifetime: 3,
})
```

## 运动

### 重力

该 `gravity` 属性是应用到场景重力（-9.81 m/s²）的乘数。将其设置为 `0` 可让粒子悬浮不动，设置为负值可将其向上推，设置为正值可加速其向下运动。

```ts
ParticleSystem.create(emitter, {
	gravity: -0.5, // 粒子缓慢向上漂浮
})
```

### 初始速度

`initialVelocitySpeed` 是一个 `FloatRange` 它设置每个粒子发射时随机速度范围的最小值和最大值（m/s）。两个值默认都是 `1`.

```ts
ParticleSystem.create(emitter, {
	initialVelocitySpeed: { start: 2, end: 8 },
})
```

### 额外力

除重力外，每帧作用于所有粒子的恒定力向量。适用于风或磁力效果。

```ts
ParticleSystem.create(emitter, {
	additionalForce: Vector3.create(0.5, 0, 0), // 恒定的侧向推动
})
```

### 速度限制

使用 `limitVelocity` 用于限制粒子的最大速度，并可选择在每一帧削减其超出部分的速度。

```ts
ParticleSystem.create(emitter, {
	limitVelocity: {
		speed: 5, // 允许的最大速度（m/s）
		dampen: 0.8, // 每帧移除的超额速度比例
	},
})
```

## 视觉属性

### 颜色

`initialColor` 设置粒子出生时的颜色，在给定范围内随机选取。 `colorOverTime` 使粒子的颜色逐渐从 `起始` 添加到 `结束` 值在粒子寿命期间变化。两者都接受一个 `ColorRange` 搭配一个 `起始` 和 `结束` 值。

```ts
import { Color4 } from '@dcl/sdk/math'

ParticleSystem.create(emitter, {
	initialColor: {
		start: Color4.create(1, 0.5, 0, 1), // 橙色
		end: Color4.create(1, 1, 0, 1), // 黄色
	},
	colorOverTime: {
		start: Color4.create(0.5, 0, 0, 0.5), // 暗红色，半透明
		end: Color4.create(0, 0, 0, 0), // 完全透明（淡出）
	},
})
```

请注意，中的第 4 个值 `Color4` 是 *alpha*alpha。如果你将最终颜色设置为 alpha 为 0 的颜色，粒子会逐渐淡出并变得不可见，这通常是个不错的效果。

### 大小

`initialSize` 和 `sizeOverTime` 是 `FloatRange` 值列表。 `initialSize` 控制粒子出生时的缩放比例，在给定范围内随机选取。 `sizeOverTime` 使粒子的缩放逐渐从 `起始` 添加到 `结束` 值在粒子寿命期间变化。值为 `1` 等于原始纹理大小。

```ts
ParticleSystem.create(emitter, {
	initialSize: { start: 0.1, end: 0.3 },
	sizeOverTime: { start: 0.5, end: 1.0 }, // 在生命周期内增长
})
```

{% hint style="warning" %}
**📔 注意**：该 `缩放` 实体的 `Transform` 不会影响粒子的缩放。
{% endhint %}

### 纹理

默认情况下，粒子会渲染为白色方块。提供纹理即可使用自定义图像。

```ts
ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/Images/spark.png' },
})
```

### 混合模式

控制粒子颜色如何与其背后的场景进行合成。

| 值                                      | 描述                        |
| -------------------------------------- | ------------------------- |
| `ParticleSystemBlendMode.PSB_ALPHA`    | 标准透明度（默认）。                |
| `ParticleSystemBlendMode.PSB_ADD`      | 加色混合——粒子会使场景更亮。适合火焰和发光效果。 |
| `ParticleSystemBlendMode.PSB_MULTIPLY` | 将粒子颜色与其背后的场景相乘。           |

```ts
import { ParticleSystemBlendMode } from '@dcl/sdk/ecs'

ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/textures/ember.png' },
	blendMode: ParticleSystemBlendMode.PSB_ADD,
})
```

### 广告牌

当 `billboard` 为 `true` （默认情况下），无论发射器方向如何，每个粒子始终面向相机。将其设置为 `false` 适用于应在 3D 空间中翻滚的粒子。

```ts
ParticleSystem.create(emitter, {
	billboard: false,
})
```

## 旋转

### 初始旋转和随时间变化的旋转

`initialRotation` 是粒子生成时的朝向。 `rotationOverTime` 是每个轴每秒施加的角速度。两者都接受一个 `Quaternion`.

```ts
import { Quaternion } from '@dcl/sdk/math'

ParticleSystem.create(emitter, {
	initialRotation: Quaternion.fromEulerDegrees(0, 0, 45),
	rotationOverTime: Quaternion.fromEulerDegrees(0, 0, 90), // 在 Z 轴上以 90°/秒旋转
})
```

{% hint style="warning" %}
**📔 注意**：如果 `billboard` 设置为 `true`，那么粒子将只会绕一个轴旋转，并始终保持面向相机的朝向。
{% endhint %}

### 朝向运动方向

当 `faceTravelDirection` 为 `true`，每个粒子都会自动旋转至指向其运动方向，就像小行星或落叶在空中下落一样。

```ts
ParticleSystem.create(emitter, {
	faceTravelDirection: true,
	billboard: false,
})
```

{% hint style="warning" %}
**📔 注意**：如果 `faceTravelDirection` 为 true 时，的值 `billboard` 将被忽略。
{% endhint %}

## 精灵图动画

你可以将纹理视为动画帧网格来为粒子制作动画。指定图集中的列数和行数以及播放速度。

```ts
ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/textures/flame-sheet.png' },
	spriteSheet: {
		tilesX: 4, // 4 列
		tilesY: 3, // 3 行（共 12 帧）
		framesPerSecond: 12,
	},
})
```

## 播放控制

粒子系统可处于由 `playbackState`.

| 值                                        | 描述                 |
| ---------------------------------------- | ------------------ |
| `ParticleSystemPlaybackState.PS_PLAYING` | 正在发射（默认）。          |
| `ParticleSystemPlaybackState.PS_PAUSED`  | 将当前所有粒子冻结在原地并停止发射。 |
| `ParticleSystemPlaybackState.PS_STOPPED` | 停止发射并移除所有现有粒子。     |

```ts
import { ParticleSystemPlaybackState } from '@dcl/sdk/ecs'

// 玩家走远时暂停
ParticleSystem.getMutable(emitter).playbackState =
	ParticleSystemPlaybackState.PS_PAUSED

// 恢复
ParticleSystem.getMutable(emitter).playbackState =
	ParticleSystemPlaybackState.PS_PLAYING
```

### 循环和预热

默认情况下，系统会无限循环。将 `loop` 为 `false` 设置为一次性效果，在所有粒子死亡后自动停止。

设置 `预热` 为 `true` （需要 `loop: true`）来模拟系统仿佛已从开始时运行，因此当玩家首次看到它时，粒子已经充满场景。

```ts
ParticleSystem.create(emitter, {
	loop: false, // 播放一次然后停止
	prewarm: false,
})
```

## 爆发式发射

爆发允许你在特定时刻发射大量粒子，而不是以恒定速率发射。它们适用于爆炸、烟花或其他一次性事件。

单个粒子系统可以经历包含多个爆发的循环，即使间隔或概率不同，也会显得更自然。

```ts
ParticleSystem.create(emitter, {
	rate: 0, // 禁用持续发射
	bursts: {
		values: [
			{
				time: 0, // 播放开始后的秒数
				count: 200, // 每次爆发发射的粒子数
				cycles: 1, // 重复多少次（0 = 无限）
				interval: 0.2, // 重复循环之间的秒数
				probability: 1, // 每个循环中爆发触发的概率为 0–1
			},
		],
	},
})
```

对于带有错开爆发的循环烟花效果：

```ts
ParticleSystem.create(emitter, {
	loop: true,
	rate: 0,
	lifetime: 2,
	bursts: {
		values: [
			{ time: 0.0, count: 80, cycles: 0, interval: 3 },
			{ time: 0.7, count: 100, cycles: 0, interval: 3 },
			{ time: 1.4, count: 60, cycles: 0, interval: 3 },
		],
	},
})
```

## 模拟空间

控制粒子是相对于发射器移动（`PSS_LOCAL`，默认）还是在生成后固定在世界坐标中（`PSS_WORLD`).

使用 `PSS_WORLD` 适用于会在移动时留下轨迹的发射器（例如小行星或火箭）。

```ts
import { PBParticleSystem_SimulationSpace } from '@dcl/sdk/ecs'

ParticleSystem.create(emitter, {
	simulationSpace: PBParticleSystem_SimulationSpace.PSS_WORLD,
})
```

## 性能

引擎会强制执行每个场景的粒子预算，并且如果总粒子数可能超过限制，就会自动降低场景中所有活动粒子系统的发射速率。请相应规划你的场景：

* 宁可使用更少但视觉冲击力更强的系统，也不要使用许多效果不明显的系统。
* 使用 `maxParticles` 用于限制单个系统的上限。
* 使用 `active` 或 `playbackState` 用于禁用屏幕外或超出范围的系统。
* 较短 `lifetime` 值可将存活粒子数保持得低于高发射 `rate` 仅从字面看起来的数量。

引擎将任意时刻可渲染的最大粒子数上限设为 1000。如果你发射的粒子超过这个数量，可能无法看到全部粒子。

还要记住，只有当玩家站在你的场景内时才能看到粒子。从场景外观看场景的玩家，直到进入场景前都不会看到任何粒子。

## 粒子实验室

进入世界 [ParticleLab.dcl.eth](decentraland://?realm=particlelab.dcl.eth\&dclenv=org) 用于试验不同的粒子系统。当你接近某个粒子系统时，界面会显示所有可用字段，你可以实时调整它们，而无需重新加载场景。满意后，点击 **复制** 按钮将该粒子系统的代码复制到剪贴板。

{% hint style="info" %}
**💡 提示**：如需一个涵盖每个 `ParticleSystem` 字段的可运行示例，请查看 [`0,7-particle-system`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,7-particle-system) 测试场景。它涵盖了全部四种发射器形状、 `PSB_ADD`/`PSB_ALPHA`/`PSB_MULTIPLY` 混合模式、 `PS_PLAYING`/`PS_PAUSED`/`PS_STOPPED` 播放状态、精灵图、持续 `rate` 与一次性和循环 `爆发`、以及 `PSS_LOCAL` 相对于 `PSS_WORLD` 在移动发射器上。
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/particle-system.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
