3.11 粒子系统 (Particle System)


文档摘要

3.11 粒子系统 (Particle System) 3.11 粒子系统 (Particle System) 粒子系统是 Unity 中一个强大且灵活的模块,用于创建和控制大量的微小图像或网格(粒子),从而模拟各种视觉效果,例如火焰、烟雾、爆炸、雨雪、魔法效果等等。粒子系统能够极大地丰富游戏和应用的视觉表现力,提升用户体验。 3.11.1 粒子系统的基本概念 在深入了解粒子系统的各个模块之前,我们需要理解几个核心概念: 粒子 (Particle):粒子系统中的基本单元,可以是图像(Sprite)、网格 (Mesh) 或其他几何形状。每个粒子都拥有生命周期、位置、速度、颜色、大小等属性,这些属性会随着时间变化,从而形成动态效果。 发射器 (Emitter):粒子系统的源头,负责生成粒子。

3.11 粒子系统 (Particle System)

3.11 粒子系统 (Particle System)

粒子系统是 Unity 中一个强大且灵活的模块,用于创建和控制大量的微小图像或网格(粒子),从而模拟各种视觉效果,例如火焰、烟雾、爆炸、雨雪、魔法效果等等。粒子系统能够极大地丰富游戏和应用的视觉表现力,提升用户体验。

3.11.1 粒子系统的基本概念

在深入了解粒子系统的各个模块之前,我们需要理解几个核心概念:

  • 粒子 (Particle):粒子系统中的基本单元,可以是图像(Sprite)、网格 (Mesh) 或其他几何形状。每个粒子都拥有生命周期、位置、速度、颜色、大小等属性,这些属性会随着时间变化,从而形成动态效果。

  • 发射器 (Emitter):粒子系统的源头,负责生成粒子。发射器定义了粒子产生的速率、形状、初始速度等。

  • 模块 (Module):粒子系统由多个模块组成,每个模块负责控制粒子生命周期的不同方面。例如,Emission 模块控制粒子的发射,Shape 模块定义发射形状,Velocity over Lifetime 模块控制粒子随时间的速度变化等。

  • 渲染器 (Renderer):负责将粒子渲染到屏幕上。渲染器决定了粒子的材质、渲染模式、混合模式等。

粒子系统工作流程 (Graph TD):

流程解释:

  1. 发射器 (Emitter) 生成粒子:根据 Emission 模块的设置,发射器在一定速率和形状下创建新的粒子。

  2. 粒子属性初始化:每个新生成的粒子都会被赋予初始属性,例如初始位置、速度、颜色、大小等。这些初始属性可以由各个模块进行设置。

  3. 模块处理:粒子系统中的各个模块开始作用,例如 Velocity over Lifetime 模块会根据时间改变粒子的速度,Size over Lifetime 模块会改变粒子的大小,等等。

  4. 粒子属性更新:根据模块的设置,粒子的属性会在每一帧被更新,例如位置会根据速度变化,颜色会根据时间梯度变化。

  5. 渲染器 (Renderer) 渲染粒子:渲染器根据粒子的材质、渲染模式等将粒子绘制到屏幕上。

  6. 显示在屏幕上:粒子最终被显示在游戏或应用的场景中,形成视觉效果。

  7. 粒子生命周期结束?:每个粒子都有一个生命周期,当粒子的生命周期结束时,粒子会被销毁,从场景中移除。如果生命周期未结束,粒子将继续进行模块处理和属性更新。

3.11.2 创建和配置粒子系统

在 Unity 中创建粒子系统非常简单:

  1. 在 Hierarchy 窗口中,右键点击,选择 Effects -> Particle System

  2. 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 组件下方,单独的组件)。

3.11.3 常用模块详解与代码实践

接下来,我们将详细讲解几个常用的粒子系统模块,并结合代码实践演示如何通过脚本控制粒子系统。

3.11.3.1 Emission 模块

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; } }

代码解释:

  1. 获取 ParticleSystem 组件和 EmissionModule

  2. Update() 函数中,根据时间或其他条件动态计算 emissionRateMultiplier,这里使用正弦波模拟波动效果。

  3. 根据 baseEmissionRatemaxEmissionRateemissionRateMultiplier 计算当前的 currentEmissionRate

  4. 使用 emissionModule.rateOverTime = currentEmissionRate; 设置 Emission 模块的 Rate over Time 属性,从而动态调整粒子的发射速率。

3.11.3.2 Shape 模块

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; } } }

代码解释:

  1. 定义 ShapeType 枚举,包含 Cone, Sphere, Box 三种 Shape 类型。

  2. 获取 ParticleSystem 组件和 ShapeModule

  3. UpdateShape() 函数根据 currentShapeType 设置不同的 Shape 类型和相应的参数 (例如 Cone 的角度、Sphere 的半径、Box 的尺寸)。

  4. Update() 函数中,监听空格键按下事件,切换 currentShapeType,并调用 UpdateShape() 更新粒子系统的 Shape。

3.11.3.3 Velocity over Lifetime 模块

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 轴速度曲线,应用修改后的曲线 } }

代码解释:

  1. 获取 ParticleSystem 组件和 VelocityOverLifetimeModule

  2. 创建一个 AnimationCurve 对象 speedXCurve,用于定义 X 轴速度随时间变化的曲线。可以在 Inspector 窗口中编辑该曲线。

  3. Start() 函数中,启用 VelocityOverLifetimeModule,并使用 new ParticleSystem.MinMaxCurve(baseSpeedX, speedXCurve) 创建 MinMaxCurve 对象,将其赋值给 velocityModule.x,从而将曲线应用到 X 轴速度。

  4. Update() 函数中,根据垂直轴输入 speedMultiplier 动态修改 speedXCurve 曲线的第二个关键帧的值,从而调整速度曲线的最大值。然后重新设置 velocityModule.x,应用修改后的曲线。

3.11.3.4 Color over Lifetime 模块

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; // 应用修改后的颜色梯度 } }

代码解释:

  1. 获取 ParticleSystem 组件和 ColorOverLifetimeModule

  2. 在 Inspector 窗口中创建一个 Gradient 类型的 baseGradient 变量,设置基础颜色梯度。

  3. Start() 函数中,启用 ColorOverLifetimeModule,并将 baseGradient 赋值给 colorModule.color,初始化颜色梯度。

  4. Update() 函数中,使用 Mathf.PingPong 创建一个 0 到 1 循环变化的时间因子 timeFactor

  5. 创建一个新的 Gradient 对象 modifiedGradient,复制 baseGradient 的颜色和 Alpha 关键帧。

  6. 使用 Color.LerpbaseGradient.colorKeys[1].colormaxColor 之间插值,根据 timeFactor 动态修改颜色梯度中间位置的颜色,实现颜色循环效果。

  7. modifiedGradient 赋值给 colorModule.color,应用修改后的颜色梯度。

3.11.4 高级粒子系统技巧

除了常用的模块,粒子系统还提供了一些高级技巧,可以创建更复杂和精美的效果:

  • Sub Emitters (子发射器):当粒子满足特定条件(例如死亡、碰撞)时,发射新的粒子系统。可以用于模拟爆炸后的碎片飞溅、烟雾消散等效果。

  • Trails (拖尾):为粒子生成拖尾效果,常用于模拟运动轨迹、魔法光束等。

  • Noise Module (噪声模块):为粒子的运动添加随机噪声,使粒子运动更加自然和有机。

  • Collision (碰撞):检测粒子与场景中碰撞体的碰撞,可以实现粒子反弹、停留、触发事件等效果。

  • External Forces (外部力场):允许外部力场(例如风场、吸引场)影响粒子,实现更复杂的运动效果。

  • Texture Sheet Animation (纹理序列帧动画):使用序列帧贴图,实现粒子动画效果,例如火焰跳动、闪电效果等。

3.11.5 粒子系统性能优化

粒子系统虽然强大,但也可能带来性能开销,尤其是在粒子数量较多、效果复杂时。以下是一些粒子系统性能优化的建议:

  • 控制粒子数量 (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):对于频繁创建和销毁的粒子系统,可以使用对象池技术,预先创建一批粒子系统,需要时从对象池中取出,使用完毕后放回对象池,避免频繁的实例化和销毁操作。

  • 简化粒子效果:在性能瓶颈设备上,可以适当简化粒子效果,例如减少粒子数量、降低粒子复杂度、使用更简单的材质等。

3.11.6 总结

粒子系统是 Unity 中非常重要的一个模块,掌握粒子系统的使用和优化技巧,能够为游戏和应用带来更加生动和吸引人的视觉效果。通过学习本文,您应该对粒子系统的基本概念、模块功能、代码实践和性能优化有了更深入的了解。希望您能够灵活运用粒子系统,创造出令人惊艳的视觉体验!

后续学习方向:

  • 深入研究各个粒子系统模块的参数和用法,例如 Collision、Triggers、Sub Emitters 等。

  • 学习使用 ShaderGraph 或 Shader 代码自定义粒子材质,实现更高级的渲染效果。

  • 探索 Unity 新的 VFX Graph 系统,它提供了更强大的可视化粒子效果编辑和控制能力。

  • 学习粒子系统的性能优化技巧,确保粒子效果在各种设备上都能流畅运行。


发布者: 作者: 转发
评论区 (0)
U