粒子系统
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();
}
}
性能优化
优化建议
-
减少粒子数量
- 使用
maxParticles限制最大数量 - 减少发射速率
- 使用
-
简化碰撞
- 使用 Plane 碰撞而非 World 碰撞
- 减少碰撞质量
-
使用 GPU 粒子
- 启用
Use GPU Instancing
- 启用
-
减少 Overdraw
- 使用较小的粒子
- 避免大量透明粒子重叠
-
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);
}
}
}
下一步
掌握粒子系统后,你可以: