VFX & Particle System
Unity 提供两套粒子系统:Particle System(基于 CPU、灵活易用)与 VFX Graph(基于 GPU、可达数百万粒子),用于火焰、烟雾、雨水、爆炸与魔法特效。按目标平台与粒子规模选型,能帮特效师与程序在表现力与帧率之间取得平衡,并与 Timeline、Prefab 工作流顺畅衔接。
想象一下...
Particle System 像手持烟花——你设发射率、角度与颜色,由 CPU 更新每个粒子。精确,但数量一大就慢。VFX Graph 是工业烟花机——全在 GPU 上并行,可跑数百万粒子,但需要强 GPU 与 URP/HDRP。按粒子数量、目标平台与行为复杂度来选。
概念详解
Particle System(又称 Shuriken)是挂在 GameObject 上的 组件,在 CPU 上创建与更新粒子。每个粒子有位置、速度、颜色、大小与寿命。模块(Emission、Shape、 Velocity、Color over Lifetime、Force、Collision…)提供精细控制。适合:小火、雨、雪、受击特效、 烟雾——数十到数千粒子。
VFX Graph(Visual Effect Graph)完全跑在 GPU compute shaders 上。用类似 Shader Graph 的节点图搭建更新逻辑(Initialize、Update、Output)。 数百万粒子仍可保持性能。要求:URP 或 HDRP、支持 Compute Shader 的 GPU(多数 2015+), 不适合较旧的 Android/iOS。
VFX Graph 把粒子分成:Spawn(速率/爆发)、 Initialize(初始属性)、Update(每帧物理、颜色、大小)、 以及 Output(如何绘制:quad、mesh、ribbon)。Context 通过数据流连接, 类似渲染管线。
性能:Particle System 在手机与主机上若保持约 1000 个活动粒子以内通常没问题。
用 maxParticles 限制,播放后设 Stop Action = Disable。
VFX Graph 扩展性更好,但务必在目标平台上做 profile。
Particle System 与 VFX Graph
| 对比项 | Particle System | VFX Graph |
|---|---|---|
| 处理 | CPU | GPU (Compute Shader) |
| 最佳粒子数量 | 100 – 10,000 | 10,000 – 10,000,000+ |
| Pipeline | Built-in, URP, HDRP | URP, HDRP only |
| Mobile | ✅ 良好 | ⚠️ 受限 |
| Interface | Inspector module | Node graph editor |
| Script API | 完整 C# API | Limited (SetFloat, SetTexture) |
| 适用场景 | 火焰、雨水、受击特效、烟雾 | 星系、流体、人群、破坏 |
动手步骤(Particle System)
创建 Particle System
GameObject → Effects → Particle System,或在现有 GameObject 上 Add Component → Particle System。
配置 Main 模块
Duration、Looping、Start Lifetime、Start Speed、Start Size、Start Color——基础参数。
选择发射形状
Shape 模块:Cone(火)、Sphere(爆炸)、Box(从上方下雨)、Circle(环)。调节 Radius 与 Arc。
启用 Color over Lifetime
加渐变:红 → 橙 → 黄 → 透明,让火焰逐渐消散。
需要时用代码播放
ps.Play() / ps.Stop() / ps.Emit(count) —— 或用 EmitParams 做瞬时爆发。
交互模拟器
调节 Particle System 参数,按 Burst / 预设查看效果。
代码示例
基础播放/停止 Particle System,并按需爆发(例如受击特效)。
using UnityEngine;
public class HitEffect : MonoBehaviour
{
public ParticleSystem sparks;
public ParticleSystem smoke;
// Call on bullet impact — PlayOneShot a prefab at a position
public static void PlayAt(Vector3 pos, Vector3 normal,
GameObject fxPrefab)
{
GameObject fx = Instantiate(fxPrefab, pos,
Quaternion.LookRotation(normal));
Destroy(fx, 2f); // Clean up after 2 seconds
}
// Burst emit: 30 particles immediately, no looping
public void BurstEmit()
{
ParticleSystem.EmitParams ep = new ParticleSystem.EmitParams();
ep.position = transform.position;
sparks.Emit(ep, 30);
smoke.Play();
}
// Change particle color at runtime via Main module
public void SetColor(Color color)
{
var main = sparks.main;
main.startColor = new ParticleSystem.MinMaxGradient(color);
}
}代码示例
进阶从 C# 驱动 VFX Graph —— 用 ExposedProperty 设属性并触发事件。
using UnityEngine;
using UnityEngine.VFX;
public class VFXController : MonoBehaviour
{
public VisualEffect vfx;
// Property IDs — must match Exposed Property names in VFX Graph
static readonly int SpawnRateID = Shader.PropertyToID("SpawnRate");
static readonly int ColorID = Shader.PropertyToID("BaseColor");
static readonly int ExplodeID = Shader.PropertyToID("OnExplode");
void Start()
{
vfx.SetFloat(SpawnRateID, 50f);
vfx.SetVector4(ColorID, new Vector4(1f, 0.5f, 0f, 1f));
}
public void Explode()
{
// SendEvent fires an event in VFX Graph (Burst spawn)
vfx.SendEvent(ExplodeID);
}
public void SetIntensity(float t)
{
// Spawn rate 0 → 500 from intensity
vfx.SetFloat(SpawnRateID, Mathf.Lerp(0f, 500f, t));
}
}📌 快速记忆
- ▸Particle System:CPU,全平台,<10k 粒子
- ▸VFX Graph:GPU,仅 URP/HDRP,可达数百万粒子
- ▸Stop Action = Disable 便于复用(对象池)
- ▸ps.main.startColor 必须作为结构体重赋
- ▸VFX Graph:SendEvent() 触发 Burst context
⚠️ 常见错误
❌ 大量生成 PS prefab 却不 Destroy
成千上万 Particle System 堆积 → 严重卡顿
✅ 池化 PS,或结束后 Destroy(fx, lifetime)
❌ 直接改 ps.main.startColor.color
结构体拷贝——改动不会生效
✅ var main = ps.main; main.startColor = new MinMaxGradient(c);