Unity Term Book
图形与特效

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 SystemVFX Graph
处理CPUGPU (Compute Shader)
最佳粒子数量100 – 10,00010,000 – 10,000,000+
PipelineBuilt-in, URP, HDRPURP, HDRP only
Mobile✅ 良好⚠️ 受限
InterfaceInspector moduleNode graph editor
Script API完整 C# APILimited (SetFloat, SetTexture)
适用场景火焰、雨水、受击特效、烟雾星系、流体、人群、破坏

动手步骤(Particle System)

1

创建 Particle System

GameObject → Effects → Particle System,或在现有 GameObject 上 Add Component → Particle System。

2

配置 Main 模块

Duration、Looping、Start Lifetime、Start Speed、Start Size、Start Color——基础参数。

3

选择发射形状

Shape 模块:Cone(火)、Sphere(爆炸)、Box(从上方下雨)、Circle(环)。调节 Radius 与 Arc。

4

启用 Color over Lifetime

加渐变:红 → 橙 → 黄 → 透明,让火焰逐渐消散。

5

需要时用代码播放

ps.Play() / ps.Stop() / ps.Emit(count) —— 或用 EmitParams 做瞬时爆发。

交互模拟器

调节 Particle System 参数,按 Burst / 预设查看效果。

存活粒子:0Mode: Fire

代码示例

基础

播放/停止 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);