3.11 粒子系统 (Particle System) 3.11 粒子系统 (Particle System) 粒子系统是 Unity 中一个强大且灵活的模块,用于创建和控制大量的微小图像或网格(粒子),从而模拟各种视觉效果,例如火焰、烟雾、爆炸、雨雪、魔法效果等等。粒子系统能够极大地丰富游戏和应用的视觉表现力,提升用户体验。 3.11.1 粒子系统的基本概念 在深入了解粒子系统的各个模块之前,我们需要理解几个核心概念: 粒子 (Particle):粒子系统中的基本单元,可以是图像(Sprite)、网格 (Mesh) 或其他几何形状。每个粒子都拥有生命周期、位置、速度、颜色、大小等属性,这些属性会随着时间变化,从而形成动态效果。 发射器 (Emitter):粒子系统的源头,负责生成粒子。
粒子系统是 Unity 中一个强大且灵活的模块,用于创建和控制大量的微小图像或网格(粒子),从而模拟各种视觉效果,例如火焰、烟雾、爆炸、雨雪、魔法效果等等。粒子系统能够极大地丰富游戏和应用的视觉表现力,提升用户体验。
在深入了解粒子系统的各个模块之前,我们需要理解几个核心概念:
粒子 (Particle):粒子系统中的基本单元,可以是图像(Sprite)、网格 (Mesh) 或其他几何形状。每个粒子都拥有生命周期、位置、速度、颜色、大小等属性,这些属性会随着时间变化,从而形成动态效果。
发射器 (Emitter):粒子系统的源头,负责生成粒子。发射器定义了粒子产生的速率、形状、初始速度等。
模块 (Module):粒子系统由多个模块组成,每个模块负责控制粒子生命周期的不同方面。例如,Emission 模块控制粒子的发射,Shape 模块定义发射形状,Velocity over Lifetime 模块控制粒子随时间的速度变化等。
渲染器 (Renderer):负责将粒子渲染到屏幕上。渲染器决定了粒子的材质、渲染模式、混合模式等。
粒子系统工作流程 (Graph TD):
流程解释:
发射器 (Emitter) 生成粒子:根据 Emission 模块的设置,发射器在一定速率和形状下创建新的粒子。
粒子属性初始化:每个新生成的粒子都会被赋予初始属性,例如初始位置、速度、颜色、大小等。这些初始属性可以由各个模块进行设置。
模块处理:粒子系统中的各个模块开始作用,例如 Velocity over Lifetime 模块会根据时间改变粒子的速度,Size over Lifetime 模块会改变粒子的大小,等等。
粒子属性更新:根据模块的设置,粒子的属性会在每一帧被更新,例如位置会根据速度变化,颜色会根据时间梯度变化。
渲染器 (Renderer) 渲染粒子:渲染器根据粒子的材质、渲染模式等将粒子绘制到屏幕上。
显示在屏幕上:粒子最终被显示在游戏或应用的场景中,形成视觉效果。
粒子生命周期结束?:每个粒子都有一个生命周期,当粒子的生命周期结束时,粒子会被销毁,从场景中移除。如果生命周期未结束,粒子将继续进行模块处理和属性更新。
在 Unity 中创建粒子系统非常简单:
在 Hierarchy 窗口中,右键点击,选择 Effects -> Particle System。
Unity 会在场景中创建一个默认的粒子系统对象,并自动添加 Particle System 组件和 Particle System Renderer 组件。
创建粒子系统后,我们可以在 Inspector 窗口中对 Particle System 组件进行详细配置。Particle System 组件包含了多个模块,每个模块控制粒子系统的不同方面。
Inspector 窗口中的主要模块:
Duration: 粒子系统发射的总时长 (秒)。
Looping: 是否循环播放粒子效果。
Prewarm: 如果 Looping 为 true,是否在开始播放前预热粒子系统,立即显示完整效果。
Start Delay: 粒子系统开始播放前的延迟时间 (秒)。
Start Lifetime: 粒子的初始生命周期,可以设置为常量或随机范围。
Start Speed: 粒子的初始速度,可以设置为常量或随机范围。
Start Size: 粒子的初始大小,可以设置为常量或随机范围。
Start Rotation: 粒子的初始旋转角度,可以设置为常量或随机范围。
Start Color: 粒子的初始颜色,可以设置为常量或颜色梯度。
Gravity Modifier: 粒子受重力影响的程度。
Simulation Space: 粒子系统模拟的空间,可以是 World (世界坐标系) 或 Local (局部坐标系)。
Play On Awake: 是否在场景加载时自动播放粒子系统。
Emitter Velocity Mode: 发射器速度模式,用于控制粒子是否继承发射器的速度。
Max Particles: 粒子系统能够同时存在的最大粒子数量,限制性能开销。
展开 Particle System 组件可以看到更多的模块 (Module):
Emission: 控制粒子的发射速率和数量。
Shape: 定义粒子的发射形状。
Velocity over Lifetime: 控制粒子生命周期内的速度变化。
Limit Velocity over Lifetime: 限制粒子生命周期内的最大速度。
Inherit Velocity: 使粒子继承发射器的速度。
Force over Lifetime: 对粒子施加力,例如风力、吸引力等。
Color over Lifetime: 控制粒子生命周期内的颜色变化。
Color by Speed: 根据粒子的速度改变颜色。
Size over Lifetime: 控制粒子生命周期内的大小变化。
Size by Speed: 根据粒子的速度改变大小。
Rotation over Lifetime: 控制粒子生命周期内的旋转变化。
Rotation by Speed: 根据粒子的速度改变旋转。
External Forces: 允许外部力场影响粒子。
Collision: 检测粒子与场景中碰撞体的碰撞。
Triggers: 根据粒子进入或离开碰撞体区域触发事件。
Sub Emitters: 当粒子死亡、碰撞或出生时,发射新的粒子系统。
Texture Sheet Animation: 动画化粒子贴图,实现帧动画效果。
Lights: 为粒子添加实时光照效果。
Trails: 为粒子生成拖尾效果。
Custom Data: 自定义粒子数据,用于高级效果。
Renderer: 粒子渲染模块,控制粒子的材质、渲染模式等(位于 Particle System 组件下方,单独的组件)。
接下来,我们将详细讲解几个常用的粒子系统模块,并结合代码实践演示如何通过脚本控制粒子系统。
Emission 模块控制粒子的发射行为。主要参数:
Rate over Time: 每秒发射的粒子数量。
Rate over Distance: 每移动单位距离发射的粒子数量 (需要粒子系统移动时生效)。
Bursts: 在特定时间点瞬间发射大量粒子。可以添加多个 Burst 事件,设置不同的时间和粒子数量。
代码实践:动态调整 Emission Rate
using UnityEngine; public class ParticleEmissionControl : MonoBehaviour { public ParticleSystem particleSystem; public float baseEmissionRate = 10f; public float maxEmissionRate = 100f; public float emissionRateMultiplier = 1f; private ParticleSystem.EmissionModule emissionModule; void Start() { if (particleSystem == null) { particleSystem = GetComponent<ParticleSystem>(); } emissionModule = particleSystem.emission; } void Update() { // 根据输入或其他条件动态调整 emissionRateMultiplier emissionRateMultiplier = Mathf.Clamp01(Mathf.Sin(Time.time)); // 例如,使用正弦波模拟波动效果 // 计算当前 Emission Rate float currentEmissionRate = baseEmissionRate + (maxEmissionRate - baseEmissionRate) * emissionRateMultiplier; // 设置 Emission Rate over Time emissionModule.rateOverTime = currentEmissionRate; } }
代码解释:
获取 ParticleSystem 组件和 EmissionModule。
在 Update() 函数中,根据时间或其他条件动态计算 emissionRateMultiplier,这里使用正弦波模拟波动效果。
根据 baseEmissionRate、maxEmissionRate 和 emissionRateMultiplier 计算当前的 currentEmissionRate。
使用 emissionModule.rateOverTime = currentEmissionRate; 设置 Emission 模块的 Rate over Time 属性,从而动态调整粒子的发射速率。
Shape 模块定义了粒子发射的形状。常用的 Shape 类型包括:
Cone: 圆锥形发射。
Sphere: 球形发射。
Hemisphere: 半球形发射。
Circle: 圆环形发射。
Edge: 线形发射。
Rectangle: 矩形发射。
Box: 立方体发射。
Mesh: 从网格表面发射。
Skinned Mesh Renderer: 从蒙皮网格渲染器表面发射。
Shape 类型图示 (Graph TD):
代码实践:切换 Shape 类型和参数
using UnityEngine; public class ParticleShapeControl : MonoBehaviour { public ParticleSystem particleSystem; private ParticleSystem.ShapeModule shapeModule; public enum ShapeType { Cone, Sphere, Box } public ShapeType currentShapeType = ShapeType.Cone; void Start() { if (particleSystem == null) { particleSystem = GetComponent<ParticleSystem>(); } shapeModule = particleSystem.shape; UpdateShape(); // 初始化 Shape } void Update() { // 模拟切换 Shape 类型 (例如,按键切换) if (Input.GetKeyDown(KeyCode.Space)) { currentShapeType = (ShapeType)(((int)currentShapeType + 1) % System.Enum.GetValues(typeof(ShapeType)).Length); UpdateShape(); } } void UpdateShape() { switch (currentShapeType) { case ShapeType.Cone: shapeModule.shapeType = ParticleSystemShapeType.Cone; shapeModule.angle = 25f; // 设置 Cone Shape 的角度 break; case ShapeType.Sphere: shapeModule.shapeType = ParticleSystemShapeType.Sphere; shapeModule.radius = 1f; // 设置 Sphere Shape 的半径 break; case ShapeType.Box: shapeModule.shapeType = ParticleSystemShapeType.Box; shapeModule.scale = new Vector3(2f, 1f, 2f); // 设置 Box Shape 的尺寸 break; } } }
代码解释:
定义 ShapeType 枚举,包含 Cone, Sphere, Box 三种 Shape 类型。
获取 ParticleSystem 组件和 ShapeModule。
UpdateShape() 函数根据 currentShapeType 设置不同的 Shape 类型和相应的参数 (例如 Cone 的角度、Sphere 的半径、Box 的尺寸)。
在 Update() 函数中,监听空格键按下事件,切换 currentShapeType,并调用 UpdateShape() 更新粒子系统的 Shape。
Velocity over Lifetime 模块控制粒子在生命周期内的速度变化。可以设置:
Linear: 线性速度,可以沿 X, Y, Z 轴方向设置速度曲线。
Orbital: 轨道速度,使粒子围绕中心点旋转。
Radial: 径向速度,使粒子向外或向内扩散/收缩。
代码实践:控制 Velocity over Lifetime 的 Linear 速度
using UnityEngine; public class ParticleVelocityControl : MonoBehaviour { public ParticleSystem particleSystem; private ParticleSystem.VelocityOverLifetimeModule velocityModule; public float baseSpeedX = 1f; public float maxSpeedX = 5f; public AnimationCurve speedXCurve; // 用于控制 X 轴速度随时间变化的曲线 void Start() { if (particleSystem == null) { particleSystem = GetComponent<ParticleSystem>(); } velocityModule = particleSystem.velocityOverLifetime; velocityModule.enabled = true; // 确保 Velocity over Lifetime 模块启用 velocityModule.x = new ParticleSystem.MinMaxCurve(baseSpeedX, speedXCurve); // 设置 X 轴速度曲线 } void Update() { // 动态调整速度曲线的最大值 (例如,根据输入) float speedMultiplier = Input.GetAxis("Vertical"); // 例如,使用垂直轴输入控制速度强度 speedXCurve.keys[1].value = baseSpeedX + (maxSpeedX - baseSpeedX) * speedMultiplier; // 修改曲线第二个关键帧的值 (假设曲线有两个关键帧) velocityModule.x = new ParticleSystem.MinMaxCurve(baseSpeedX, speedXCurve); // 重新设置 X 轴速度曲线,应用修改后的曲线 } }
代码解释:
获取 ParticleSystem 组件和 VelocityOverLifetimeModule。
创建一个 AnimationCurve 对象 speedXCurve,用于定义 X 轴速度随时间变化的曲线。可以在 Inspector 窗口中编辑该曲线。
在 Start() 函数中,启用 VelocityOverLifetimeModule,并使用 new ParticleSystem.MinMaxCurve(baseSpeedX, speedXCurve) 创建 MinMaxCurve 对象,将其赋值给 velocityModule.x,从而将曲线应用到 X 轴速度。
在 Update() 函数中,根据垂直轴输入 speedMultiplier 动态修改 speedXCurve 曲线的第二个关键帧的值,从而调整速度曲线的最大值。然后重新设置 velocityModule.x,应用修改后的曲线。
Color over Lifetime 模块控制粒子在生命周期内的颜色变化。可以使用颜色梯度 (Gradient) 定义颜色随时间的变化。
代码实践:动态修改 Color Gradient
using UnityEngine; public class ParticleColorControl : MonoBehaviour { public ParticleSystem particleSystem; private ParticleSystem.ColorOverLifetimeModule colorModule; public Gradient baseGradient; // 基础颜色梯度,在 Inspector 中设置 public Color maxColor = Color.red; // 最大颜色值 void Start() { if (particleSystem == null) { particleSystem = GetComponent<ParticleSystem>(); } colorModule = particleSystem.colorOverLifetime; colorModule.enabled = true; // 确保 Color over Lifetime 模块启用 colorModule.color = baseGradient; // 初始化颜色梯度 } void Update() { // 动态调整颜色梯度 (例如,根据时间循环改变颜色) float timeFactor = Mathf.PingPong(Time.time, 1f); // 0 到 1 循环变化的时间因子 Gradient modifiedGradient = new Gradient(); modifiedGradient.SetKeys( baseGradient.colorKeys, // 复制基础颜色关键帧 new GradientAlphaKey[] { // 修改 Alpha 关键帧,保持不变 new GradientAlphaKey(baseGradient.alphaKeys[0].alpha, baseGradient.alphaKeys[0].time), new GradientAlphaKey(baseGradient.alphaKeys[1].alpha, baseGradient.alphaKeys[1].time) } ); // 修改颜色梯度中间位置的颜色,实现颜色循环效果 modifiedGradient.colorKeys[1] = new GradientColorKey(Color.Lerp(baseGradient.colorKeys[1].color, maxColor, timeFactor), baseGradient.colorKeys[1].time); colorModule.color = modifiedGradient; // 应用修改后的颜色梯度 } }
代码解释:
获取 ParticleSystem 组件和 ColorOverLifetimeModule。
在 Inspector 窗口中创建一个 Gradient 类型的 baseGradient 变量,设置基础颜色梯度。
在 Start() 函数中,启用 ColorOverLifetimeModule,并将 baseGradient 赋值给 colorModule.color,初始化颜色梯度。
在 Update() 函数中,使用 Mathf.PingPong 创建一个 0 到 1 循环变化的时间因子 timeFactor。
创建一个新的 Gradient 对象 modifiedGradient,复制 baseGradient 的颜色和 Alpha 关键帧。
使用 Color.Lerp 在 baseGradient.colorKeys[1].color 和 maxColor 之间插值,根据 timeFactor 动态修改颜色梯度中间位置的颜色,实现颜色循环效果。
将 modifiedGradient 赋值给 colorModule.color,应用修改后的颜色梯度。
除了常用的模块,粒子系统还提供了一些高级技巧,可以创建更复杂和精美的效果:
Sub Emitters (子发射器):当粒子满足特定条件(例如死亡、碰撞)时,发射新的粒子系统。可以用于模拟爆炸后的碎片飞溅、烟雾消散等效果。
Trails (拖尾):为粒子生成拖尾效果,常用于模拟运动轨迹、魔法光束等。
Noise Module (噪声模块):为粒子的运动添加随机噪声,使粒子运动更加自然和有机。
Collision (碰撞):检测粒子与场景中碰撞体的碰撞,可以实现粒子反弹、停留、触发事件等效果。
External Forces (外部力场):允许外部力场(例如风场、吸引场)影响粒子,实现更复杂的运动效果。
Texture Sheet Animation (纹理序列帧动画):使用序列帧贴图,实现粒子动画效果,例如火焰跳动、闪电效果等。
粒子系统虽然强大,但也可能带来性能开销,尤其是在粒子数量较多、效果复杂时。以下是一些粒子系统性能优化的建议:
控制粒子数量 (Max Particles):合理设置 Max Particles 属性,限制粒子系统的最大粒子数量,避免过度消耗性能。
减少 Overdraw (过度绘制):粒子渲染通常会产生 Overdraw,即像素被多次绘制。尽量使用简单的粒子形状和材质,避免透明粒子重叠过多。
使用合适的渲染模式 (Render Mode):根据效果需求选择合适的渲染模式,例如 Billboard (公告牌) 模式在粒子数量较多时性能较好,Mesh (网格) 模式可以实现更复杂的形状,但性能开销较大。
开启 Culling Mode (裁剪模式):在 Renderer 模块中,可以设置 Culling Mode 为 Pause And Catchup 或 Culling Mode Always Simulate,当粒子系统不可见时暂停或继续模拟,减少不必要的渲染和计算。
合并粒子系统 (Particle System Pooling):对于频繁创建和销毁的粒子系统,可以使用对象池技术,预先创建一批粒子系统,需要时从对象池中取出,使用完毕后放回对象池,避免频繁的实例化和销毁操作。
简化粒子效果:在性能瓶颈设备上,可以适当简化粒子效果,例如减少粒子数量、降低粒子复杂度、使用更简单的材质等。
粒子系统是 Unity 中非常重要的一个模块,掌握粒子系统的使用和优化技巧,能够为游戏和应用带来更加生动和吸引人的视觉效果。通过学习本文,您应该对粒子系统的基本概念、模块功能、代码实践和性能优化有了更深入的了解。希望您能够灵活运用粒子系统,创造出令人惊艳的视觉体验!
后续学习方向:
深入研究各个粒子系统模块的参数和用法,例如 Collision、Triggers、Sub Emitters 等。
学习使用 ShaderGraph 或 Shader 代码自定义粒子材质,实现更高级的渲染效果。
探索 Unity 新的 VFX Graph 系统,它提供了更强大的可视化粒子效果编辑和控制能力。
学习粒子系统的性能优化技巧,确保粒子效果在各种设备上都能流畅运行。