跳到主要内容

粒子系统

Unity 的 Particle System 可以创建各种视觉特效,如火焰、烟雾、爆炸、魔法效果等。

粒子系统概述

粒子系统核心概念:
├── Particle System - 粒子发射器组件
├── Particle - 单个粒子(有生命周期)
├── Emitter - 发射器(控制粒子生成)
└── Modules - 模块(控制粒子行为)

创建粒子系统

GameObject > Effects > Particle System

或使用代码创建:

public class ParticleSpawner : MonoBehaviour
{
public ParticleSystem particlePrefab;

void SpawnParticles()
{
// 实例化粒子系统
ParticleSystem ps = Instantiate(particlePrefab, transform.position, Quaternion.identity);

// 播放
ps.Play();

// 销毁(粒子播放完后)
Destroy(ps.gameObject, ps.main.duration + ps.main.startLifetime.constant);
}
}

主要模块

Main Module(主模块)

控制粒子系统的基本属性:

public class ParticleMainModule : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var main = ps.main;

// 持续时间
main.duration = 5f;

// 循环播放
main.loop = true;

// 预热(循环时从中间状态开始)
main.prewarm = true;

// 开始延迟
main.startDelay = 0f;

// 生命周期
main.startLifetime = 5f;
main.startLifetime = new ParticleSystem.MinMaxCurve(2f, 5f); // 随机范围

// 开始速度
main.startSpeed = 5f;

// 开始大小
main.startSize = 1f;

// 开始颜色
main.startColor = Color.white;
main.startColor = new ParticleSystem.MinMaxGradient(Color.red, Color.yellow);

// 重力
main.gravityModifier = 0.5f;

// 最大粒子数
main.maxParticles = 1000;

// 播放模式
main.playOnAwake = true;
}
}

Emission Module(发射模块)

控制粒子发射速率:

public class ParticleEmission : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var emission = ps.emission;

// 启用发射
emission.enabled = true;

// 发射速率(每秒)
emission.rateOverTime = 50;

// 距离发射(移动时发射)
emission.rateOverDistance = 10;

// 爆发发射
var burst = new ParticleSystem.Burst(0f, 100); // 0秒时发射100个
emission.SetBursts(new ParticleSystem.Burst[] { burst });
}

// 代码触发爆发
public void TriggerBurst()
{
var emission = ps.emission;
ps.Emit(100); // 立即发射100个粒子
}
}

Shape Module(形状模块)

控制粒子发射形状:

public class ParticleShape : MonoBehaviour
{
public ParticleSystem ps;

void SetShape()
{
var shape = ps.shape;

// 形状类型
shape.shapeType = ParticleSystemShapeType.Cone;
// 其他选项:Sphere, Box, Circle, Edge, Mesh...

// 圆锥角度
shape.angle = 25f;

// 圆锥半径
shape.radius = 1f;

// 从边缘发射
shape.radiusThickness = 0f; // 0 = 边缘,1 = 整个表面

// 弧形角度(Cone、Circle 等)
shape.arc = 360f;

// 随机方向
shape.randomDirectionAmount = 0f;
}
}

Velocity Over Lifetime(生命周期速度)

public class ParticleVelocity : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var velocity = ps.velocityOverLifetime;
velocity.enabled = true;

// 线性速度
velocity.x = 1f;
velocity.y = new ParticleSystem.MinMaxCurve(0f, 5f);

// 轨道速度(螺旋效果)
velocity.orbitalX = 2f;
velocity.orbitalY = 0f;
velocity.orbitalZ = 0f;

// 轨道偏移
velocity.offsetX = 1f;
}
}

Color Over Lifetime(生命周期颜色)

public class ParticleColor : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var color = ps.colorOverLifetime;
color.enabled = true;

// 创建渐变
Gradient grad = new Gradient();
grad.SetKeys(
new GradientColorKey[] {
new GradientColorKey(Color.red, 0f),
new GradientColorKey(Color.yellow, 0.5f),
new GradientColorKey(Color.black, 1f)
},
new GradientAlphaKey[] {
new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 0.5f),
new GradientAlphaKey(0f, 1f)
}
);

color.color = new ParticleSystem.MinMaxGradient(grad);
}
}

Size Over Lifetime(生命周期大小)

public class ParticleSize : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var size = ps.sizeOverLifetime;
size.enabled = true;

// 使用曲线
AnimationCurve curve = new AnimationCurve();
curve.AddKey(0f, 0f); // 开始时大小为0
curve.AddKey(0.5f, 1f); // 中间达到最大
curve.AddKey(1f, 0f); // 结束时消失

size.size = new ParticleSystem.MinMaxCurve(1f, curve);
}
}

Rotation Over Lifetime(生命周期旋转)

public class ParticleRotation : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var rotation = ps.rotationOverLifetime;
rotation.enabled = true;

// 旋转速度
rotation.z = 180f; // 每秒旋转180度

// 随机旋转
var rot = ps.startRotation;
rot.constant = Mathf.PI / 4; // 45度
}
}

Force Over Lifetime(生命周期受力)

public class ParticleForce : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var force = ps.forceOverLifetime;
force.enabled = true;

// 随机力
force.x = new ParticleSystem.MinMaxCurve(-1f, 1f);
force.y = new ParticleSystem.MinMaxCurve(0f, 2f);
force.z = new ParticleSystem.MinMaxCurve(-1f, 1f);

// 世界空间或本地空间
force.space = ParticleSystemSimulationSpace.World;
}
}

Collision Module(碰撞模块)

public class ParticleCollision : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var collision = ps.collision;
collision.enabled = true;

// 碰撞类型
collision.type = ParticleSystemCollisionType.World;
// 或 Plane(与平面碰撞)

// 反弹
collision.bounce = 0.5f;

// 生命周期损失
collision.lifetimeLoss = 0.5f;

// 最小杀死速度
collision.minKillSpeed = 1f;

// 发送碰撞消息
collision.sendCollisionMessages = true;
}

// 接收粒子碰撞事件
void OnParticleCollision(GameObject other)
{
Debug.Log("粒子碰撞:" + other.name);
}
}

Trails Module(拖尾模块)

public class ParticleTrails : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var trails = ps.trails;
trails.enabled = true;

// 拖尾比率
trails.ratio = 0.5f;

// 生命周期
trails.lifetime = 0.5f;

// 最小顶点距离
trails.minVertexDistance = 0.1f;

// 纹理模式
trails.textureMode = ParticleSystemTrailTextureMode.Stretch;

// 拖尾宽度
trails.widthOverTrail = 0.5f;
}
}

Renderer Module(渲染器模块)

public class ParticleRenderer : MonoBehaviour
{
public ParticleSystem ps;

void Start()
{
var renderer = ps.GetComponent<ParticleSystemRenderer>();

// 渲染模式
renderer.renderMode = ParticleSystemRenderMode.Billboard; // 始终面向相机
// 其他选项:Stretch(拉伸)、HorizontalBillboard、VerticalBillboard、Mesh

// 材质
renderer.material = someMaterial;

// 排序层级
renderer.sortingLayerName = "Effects";
renderer.sortingOrder = 10;

// 阴影
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
renderer.receiveShadows = false;
}
}

常用特效示例

火焰效果

public class FireEffect : MonoBehaviour
{
public ParticleSystem firePS;

void Start()
{
var main = firePS.main;
main.startLifetime = new ParticleSystem.MinMaxCurve(0.5f, 1f);
main.startSpeed = new ParticleSystem.MinMaxCurve(1f, 3f);
main.startSize = new ParticleSystem.MinMaxCurve(0.5f, 1f);
main.startColor = new ParticleSystem.MinMaxGradient(Color.yellow, Color.red);
main.gravityModifier = -0.5f; // 向上飘

var emission = firePS.emission;
emission.rateOverTime = 50;

var shape = firePS.shape;
shape.shapeType = ParticleSystemShapeType.Cone;
shape.angle = 10f;
shape.radius = 0.5f;

var color = firePS.colorOverLifetime;
color.enabled = true;
Gradient grad = new Gradient();
grad.SetKeys(
new GradientColorKey[] {
new GradientColorKey(Color.yellow, 0f),
new GradientColorKey(Color.red, 0.3f),
new GradientColorKey(Color.black, 1f)
},
new GradientAlphaKey[] {
new GradientAlphaKey(0f, 0f),
new GradientAlphaKey(1f, 0.1f),
new GradientAlphaKey(0f, 1f)
}
);
color.color = grad;

var size = firePS.sizeOverLifetime;
size.enabled = true;
AnimationCurve curve = new AnimationCurve();
curve.AddKey(0f, 0.5f);
curve.AddKey(0.5f, 1f);
curve.AddKey(1f, 0f);
size.size = curve;
}
}

爆炸效果

public class ExplosionEffect : MonoBehaviour
{
public ParticleSystem explosionPS;

public void Explode()
{
var main = explosionPS.main;
main.duration = 0.5f;
main.loop = false;
main.startLifetime = 1f;
main.startSpeed = 10f;
main.startSize = 2f;

var emission = explosionPS.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] {
new ParticleSystem.Burst(0f, 100)
});

var shape = explosionPS.shape;
shape.shapeType = ParticleSystemShapeType.Sphere;
shape.radius = 0.1f;

explosionPS.Play();
}
}

下雨效果

public class RainEffect : MonoBehaviour
{
public ParticleSystem rainPS;

void Start()
{
var main = rainPS.main;
main.startLifetime = 2f;
main.startSpeed = 20f;
main.startSize = 0.1f;
main.gravityModifier = 1f;

var emission = rainPS.emission;
emission.rateOverTime = 500;

var shape = rainPS.shape;
shape.shapeType = ParticleSystemShapeType.Box;
shape.scale = new Vector3(20f, 1f, 20f);

var velocity = rainPS.velocityOverLifetime;
velocity.enabled = true;
velocity.x = new ParticleSystem.MinMaxCurve(-2f, 2f);

var collision = rainPS.collision;
collision.enabled = true;
collision.type = ParticleSystemCollisionType.World;
collision.lifetimeLoss = 1f; // 碰撞后消失
}
}

粒子系统控制

public class ParticleController : MonoBehaviour
{
public ParticleSystem ps;

void Update()
{
// 播放
if (Input.GetKeyDown(KeyCode.P))
ps.Play();

// 暂停
if (Input.GetKeyDown(KeyCode.S))
ps.Pause();

// 停止
if (Input.GetKeyDown(KeyCode.X))
ps.Stop();

// 检查是否正在播放
if (ps.isPlaying)
Debug.Log("粒子正在播放");

// 检查是否有粒子存活
if (ps.particleCount > 0)
Debug.Log($"存活粒子数:{ps.particleCount}");
}

// 改变粒子属性
public void ChangeColor(Color newColor)
{
var main = ps.main;
main.startColor = newColor;
}

// 清除所有粒子
public void Clear()
{
ps.Clear();
}
}

性能优化

优化建议

  1. 减少粒子数量

    • 使用 maxParticles 限制最大数量
    • 减少发射速率
  2. 简化碰撞

    • 使用 Plane 碰撞而非 World 碰撞
    • 减少碰撞质量
  3. 使用 GPU 粒子

    • 启用 Use GPU Instancing
  4. 减少 Overdraw

    • 使用较小的粒子
    • 避免大量透明粒子重叠
  5. LOD 系统

    public class ParticleLOD : MonoBehaviour
    {
    public ParticleSystem highQualityPS;
    public ParticleSystem lowQualityPS;

    void Update()
    {
    float distance = Vector3.Distance(transform.position, Camera.main.transform.position);

    if (distance > 50f)
    {
    highQualityPS.gameObject.SetActive(false);
    lowQualityPS.gameObject.SetActive(true);
    }
    else
    {
    highQualityPS.gameObject.SetActive(true);
    lowQualityPS.gameObject.SetActive(false);
    }
    }
    }

下一步

掌握粒子系统后,你可以:

  1. 学习 音频系统 添加音效和音乐
  2. 了解 动画系统 制作角色动画
  3. 探索 物理系统 实现真实的物理效果