Unity粒子系统实战:5分钟构建交互式节日烟花特效
1. 项目概述从零到一用Unity粒子系统快速构建节日烟花每次看到游戏里或者影视作品中那些绚烂的烟花你是不是也好奇过它们是怎么做出来的作为一个在游戏开发一线摸爬滚打了十多年的老鸟我可以负责任地告诉你用Unity的粒子系统来实现烟花特效远比你想象的要简单。今天我就带你抛开那些复杂的理论直接上手用5分钟的时间从零开始搭建一个可以交互、效果丰富的节日烟花特效并且我会把完整的工程文件分享给你让你可以直接拿来就用或者作为你深入学习粒子系统的起点。这个项目的核心就是Unity内置的粒子系统 (Particle System)。它本质上是一个模拟大量微小粒子比如火花、烟雾、光点行为并渲染它们的工具。对于烟花来说它完美契合了需求一个主粒子烟花弹发射升空在顶点爆炸生成无数个带有拖尾、颜色变化、受重力影响下落的次级粒子。整个过程听起来复杂但通过粒子系统模块化的参数调整我们可以像搭积木一样分步骤、分层次地构建出来。无论你是刚接触Unity的新手想找个有趣的项目练手还是有一定经验的开发者想优化自己的特效制作流程这篇实战指南都能给你带来直接的帮助。我们不止要做出效果更要理解每个参数调整背后的“为什么”这样你才能举一反三做出属于自己的独特特效。2. 烟花特效的核心设计思路拆解在动手之前我们得先想明白一个烟花从发射到消失整个物理过程是怎样的。这决定了我们如何用粒子系统来“分镜”实现。一个标准的节日烟花通常包含三个阶段对应着我们将要创建的三个核心粒子系统。2.1 阶段分解升空、爆炸与消散第一阶段升空 (Rocket)这是烟花的起点。我们需要一个粒子以较快的初速度垂直向上发射。这个粒子本身通常是一个拖曳着细长尾迹的“弹头”。在Unity中我们会创建一个粒子系统来模拟它。关键点在于发射速率极低一次只发射一个粒子寿命适中模拟飞到空中所需时间并且需要一条拖尾 (Trail)来增强运动感。这个粒子在生命周期结束时并不会直接消失而是会触发爆炸这就是我们下一阶段的内容。第二阶段爆炸 (Burst)这是烟花最绚烂的核心。当升空粒子到达预定高度即生命周期结束时我们需要瞬间爆发出大量的粒子。这些粒子会以一个球形的形状向四面八方散开。这个阶段的效果决定了烟花的“花样”。我们需要关注粒子的初始速度、大小、颜色以及它们的渲染材质。通常我们会使用一个带有光晕Additive Shader的材质球来让粒子看起来像发光的小火星。第三阶段下落与拖尾 (Sparkle Trail)爆炸产生的粒子并不是静止的它们会受到模拟的“重力”影响开始向下坠落。同时在坠落过程中每个小火星本身也可以再拖出一条细微的、逐渐消失的尾迹让整个爆炸团看起来更饱满、动态感更强。这个阶段通常通过为爆炸粒子系统添加子发射器 (Sub Emitters)或者在粒子生命周期内叠加速度变化 (Velocity over Lifetime)和受力 (Force over Lifetime)模块来实现。理解了这三个阶段我们的制作思路就清晰了我们将创建至少三个相互关联的粒子系统分别负责升空、爆炸主体和爆炸粒子的拖尾效果并通过子发射器将它们串联成一个完整的链条。2.2 工具选型为什么是Unity标准粒子系统你可能会问市面上有很多强大的第三方粒子插件如VFX Graph, 更早的Shuriken插件等为什么我们选择用Unity的标准粒子系统原因很简单通用、高效、学习曲线平缓。Unity的标准粒子系统在Hierarchy中通过Effects - Particle System创建是Unity引擎内置的无需安装任何额外插件兼容性从旧版到新版Unity都保持得很好。它的编辑器是可视化的所有参数都以模块Module的形式呈现你可以实时在Scene视图中看到调整效果这对于学习和快速迭代至关重要。虽然像VFX Graph基于节点功能更强大更适合复杂的GPU粒子模拟但对于“烟花”这种经典的特效标准粒子系统完全够用且性能开销更可控特别适合移动端项目或初学者快速上手。注意在创建粒子系统时确保你的项目渲染管线支持。如果是内置渲染管线Built-in RP或通用渲染管线URP标准粒子系统都能完美工作。如果使用的是高清渲染管线HDRP粒子系统的部分材质和渲染设置可能需要适配HDRP的Lit或Unlit Shader但核心逻辑不变。本文以最通用的内置渲染管线为例进行讲解。3. 核心模块参数详解与实操要点现在我们进入实战环节。我会带你一步步创建每个粒子系统并重点讲解那些对烟花效果起决定性作用的核心模块。请打开Unity创建一个新项目或新场景跟着我一起操作。3.1 创建与基础设置从空白到雏形首先在Hierarchy面板右键选择Effects - Particle System创建一个新的粒子系统。将其命名为Firework_Rocket烟花火箭。选中它在Inspector面板中你会看到一长串可折叠的模块列表。我们先从最顶部的Particle System主模块和Emission发射模块开始。主模块 (Main Module) 这是粒子系统的总控台。我们需要调整几个关键参数Duration: 发射持续时间。对于升空火箭我们只发射一次所以这个值可以设置为1秒但更重要的是通过Start Lifetime来控制单个粒子的存活时间。Start Lifetime: 粒子初始寿命。设为3。这模拟了火箭飞到爆炸点所需的时间。Start Speed: 粒子初始速度。设为15。这个值决定了火箭升空的快慢。Start Size: 粒子初始大小。设为0.2。火箭弹头本身不需要太大。Start Color: 粒子初始颜色。设为亮黄色RGB: 255, 220, 50。这是火箭尾焰的颜色。Max Particles: 最大粒子数。设为100足够因为我们同时存在的粒子很少。发射模块 (Emission Module) 这个模块控制粒子如何被“生产”出来。Rate over Time: 随时间发射的速率。对于火箭我们不需要持续发射所以把它设为0。Bursts: 粒子爆发。点击右下角的号添加一个爆发。设置Time为0.0游戏一开始就发射Count为1Cycles为1。这样在游戏开始时这个系统就会发射出一枚火箭粒子。完成这些后点击场景视图上方的粒子系统Play按钮你应该能看到一个黄色的小点快速向上飞起然后消失。这就是我们火箭的雏形了。3.2 塑造粒子形态渲染、形状与拖尾一个光秃秃的点可不像火箭。接下来我们通过Renderer渲染器、Shape形状和Trail拖尾模块来赋予它形态。渲染器模块 (Renderer Module) 展开Renderer这里决定了粒子最终被画成什么样子。Render Mode: 渲染模式。对于发光的粒子如火星、火焰我们通常选择Billboard广告牌始终面向相机或Stretched Billboard拉伸广告牌模拟运动模糊。这里选Billboard。Material: 材质。这是最关键的一步我们需要一个能让粒子发亮、叠加的材质。在Project面板右键Create - Material命名为Particle_Additive。选中这个材质在Inspector里将Shader从Standard改为Particles - Standard Unlit或者Particles - Additive。Additive叠加着色器会让粒子的颜色相互叠加越亮的地方越白非常适合发光特效。将创建好的材质球拖拽到Material属性栏。现在你的火箭粒子应该变成一个发光的方形片了。形状模块 (Shape Module) 形状模块定义了粒子从哪个区域发射出来。对于火箭我们希望它从一个精确的点发射。勾选Shape模块。Shape: 形状类型。选择Sphere球体。Radius: 半径。设为0.01。这几乎就是一个点。这样能确保所有火箭粒子都从同一个位置发射轨迹一致。轨迹渲染模块 (Trail Module) 拖尾是表现火箭速度感的核心。勾选Trails模块。Mode: 模式。选择Particles即每个粒子都拥有自己的拖尾。Width over Trail: 拖尾宽度随时间变化。你可以使用曲线编辑器让拖尾从头到尾逐渐变细。简单设置可以给一个固定值比如0.05。Color over Trail: 拖尾颜色随时间变化。点击曲线图右侧的小齿轮选择Gradient渐变。在渐变编辑器里将左端起始设为半透明的亮黄色右端结束设为完全透明。这样拖尾就会逐渐消失。Lifetime: 拖尾的存活时间。设为0.5。这个时间决定了拖尾的长度。现在再次播放你应该能看到一个带着明亮拖尾的火箭升空了这已经很有感觉了。3.3 模拟物理运动速度、旋转与受力真实的烟花升空并非完全匀速直线而且爆炸后的碎片运动更加复杂。我们需要用以下模块来模拟物理规律。生命周期速度模块 (Velocity over Lifetime) 这个模块允许你控制粒子在其生命周期内速度的变化。对于爆炸后的碎片我们希望它们初始速度很快然后因为空气阻力慢慢减速。勾选Velocity over Lifetime。你可以分XYZ轴设置速度。对于爆炸粒子我们更常用的是Space选择Local本地空间然后给一个随机的、向外的速度。例如将X, Y, Z都设为Random Between Two Constants在两个常数间随机最小值-5最大值5。这样每个碎片的速度方向和大小都略有不同爆炸效果更自然。生命周期受力模块 (Force over Lifetime) 这是模拟重力的关键勾选Force over Lifetime。将Space设为World世界空间因为重力是世界空间下的一个恒定向下的力。在Z轴Unity中垂直向上的轴是Y但重力通常被模拟为向下的力这里根据你的场景坐标系调整。通常我们调整Y轴为负值来模拟重力输入一个负值比如Y: -10。这意味着粒子在整个生命周期中会持续受到一个向下的“力”从而做出抛物线运动。这是让爆炸碎片“坠落”而不是飘在空中的核心参数。生命周期旋转模块 (Rotation over Lifetime) 让粒子在飞行过程中自身旋转可以增加细节和随机感。勾选Rotation over Lifetime。将Angular Velocity角速度设为Random Between Two Constants例如50和150。这样每个粒子都会以不同的速度旋转。实操心得调整Force over Lifetime的数值时需要和粒子的Start Lifetime寿命以及Start Speed初速度一起考量。如果重力太大而寿命太短粒子可能还没来得及散开就掉下去了如果初速度太大而重力太小粒子可能会飞得太远。多尝试几组数值找到最符合你心中烟花效果的平衡点。4. 构建完整的烟花特效链单个粒子系统只能表现一个阶段。现在我们要把升空、爆炸、拖尾这三个阶段串联起来形成一个自动触发的特效链。这里的关键技术是子发射器 (Sub Emitters)。4.1 创建爆炸与拖尾粒子系统首先仿照前面的步骤再创建两个粒子系统Firework_Burst(爆炸主体)这个系统负责在火箭到达顶点时爆发出大量的火星。Start Lifetime: 设为2火星在空中存留时间。Start Speed: 设为Random Between Two Constants, 5 到 15爆炸初速度有快有慢。Start Size: 设为Random Between Two Constants, 0.05 到 0.2火星大小不一。Start Color: 设为随机颜色。点击Start Color下拉框选择Random Between Two Colors一端设为橙色一端设为白色这样爆炸颜色会更丰富。Emission: 将Rate over Time设为0。在Bursts里添加一个爆发Time为0.0,Count设为50一次爆炸产生50个火星。Shape: 勾选形状选SphereRadius设为0.1从一个很小的球体空间内爆发。Renderer: 材质使用之前创建的Particle_Additive。Velocity over Lifetime: 勾选给一些随机值如X,Y,Z在 -3 到 3 之间。Force over Lifetime: 勾选Y轴设为-5比重力小一些让火星飘得久一点。Rotation over Lifetime: 勾选给一个随机角速度。Firework_SparkTrail(火星拖尾)这个系统将作为爆炸火星的子效果为每个火星添加下落的轨迹。Start Lifetime: 设为0.5拖尾很短。Start Speed: 设为0拖尾本身不主动运动跟随父粒子。Start Size: 设为0.02非常细。Start Color: 设为半透明的黄色。Emission:Rate over Time设为20持续发射形成连续轨迹。Shape: 勾选形状选SphereRadius设为0.01。Renderer: 材质同样用Particle_Additive。重要在这个粒子系统的Main Module顶部取消勾选Looping循环。我们不希望拖尾无限循环。4.2 使用子发射器进行链接子发射器模块允许一个粒子系统在特定事件如出生、死亡、碰撞时触发另一个粒子系统。这正是我们需要的火箭死亡时触发爆炸爆炸粒子存活期间持续产生拖尾。链接爆炸到火箭选中Firework_Rocket火箭。勾选Sub Emitters模块。你会看到Birth出生、Collision碰撞、Death死亡等事件。点击Death事件右侧的圆圈小图标在弹出的选择窗口中找到并选择我们刚才创建的Firework_Burst爆炸主体粒子系统。现在当火箭粒子生命周期结束时即飞到顶点Firework_Burst系统就会被触发一次。链接拖尾到爆炸火星选中Firework_Burst爆炸主体。勾选它的Sub Emitters模块。这次我们点击Birth事件右侧的圆圈图标选择Firework_SparkTrail火星拖尾粒子系统。注意将Firework_SparkTrail游戏对象拖拽到Firework_Burst游戏对象下使其成为后者的子物体。这一步至关重要它能确保拖尾粒子的位置正确地跟随其父爆炸粒子。现在Firework_Burst系统每诞生一个火星粒子即爆炸时产生的50个火星之一都会同时触发一个Firework_SparkTrail系统。由于Firework_SparkTrail的发射速率是持续的它会在这个火星的存活期内持续发射出细小的拖尾粒子形成轨迹。至此一个完整的、自动播放的烟花特效链就搭建完成了将Firework_Rocket放到场景中运行游戏你应该能看到火箭拖着尾焰升空 - 到达顶点爆炸成一团彩色的火星 - 每个火星都拖着细小的尾迹在模拟的重力作用下缓缓坠落。4.3 整合与优化创建一键发射的预制体目前我们的烟花是自动播放一次。为了能重复发射和交互我们最好将其做成一个预制体Prefab并用脚本控制。在Hierarchy中创建一个空的GameObject命名为Firework_Complete。将Firework_Rocket、Firework_Burst、Firework_SparkTrail三个粒子系统都拖拽成为Firework_Complete的子物体。确保层级关系是Firework_Complete(父) -Firework_Rocket(子) -Firework_Burst(孙通过子发射器链接) -Firework_SparkTrail(曾孙通过子发射器链接且是Firework_Burst的子物体)。选中Firework_Complete在Inspector顶部点击Particle System组件旁边的齿轮图标选择Stop让它在游戏开始时处于停止状态。将Firework_Complete从Hierarchy拖拽到Project面板的Assets文件夹中这样就创建了一个预制体。删除场景中的Firework_Complete实例我们通过脚本来动态生成它。5. 编写交互脚本与效果增强一个只会自动播放的烟花还不够酷让我们给它加上鼠标点击发射的功能并进一步美化效果。5.1 鼠标点击发射脚本解析创建一个C#脚本命名为FireworkLauncher.cs将其挂载到场景中的主摄像机或一个空物体上。using UnityEngine; public class FireworkLauncher : MonoBehaviour { public GameObject fireworkPrefab; // 在Inspector中拖入我们刚创建的烟花预制体 public float launchHeight 20.0f; // 预设的爆炸高度 void Update() { // 检测鼠标左键点击 if (Input.GetMouseButtonDown(0)) { // 从摄像机发射一条射线到鼠标点击的屏幕位置 Ray ray Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; // 假设地面或其他物体有Collider用于确定发射目标点 if (Physics.Raycast(ray, out hit)) { // 计算发射起始位置地面点击点 Vector3 launchPos hit.point; launchPos.y 0; // 假设地面高度为0 // 在发射位置实例化烟花预制体 GameObject newFirework Instantiate(fireworkPrefab, launchPos, Quaternion.identity); // 获取火箭粒子系统组件 ParticleSystem rocketPS newFirework.GetComponentInChildrenParticleSystem(); if (rocketPS ! null) { // 清除可能存在的旧粒子并播放新的 rocketPS.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); rocketPS.Play(); // **关键计算动态调整火箭速度和寿命以命中目标高度** // 由于我们的爆炸是由火箭粒子死亡触发的所以需要让火箭在到达launchHeight时刚好死亡。 // 已知火箭初速度Start Speed我们在粒子系统中预设为15。 // 根据匀加速运动公式h v0*t 0.5*a*t^2。这里简化忽略空气阻力a为0火箭模块未加力。 // 所以飞行时间 t 目标高度h / 初速度v0。 float rocketSpeed rocketPS.main.startSpeed.constant; float requiredLifetime launchHeight / rocketSpeed; // 动态修改主模块的起始寿命 var mainModule rocketPS.main; mainModule.startLifetime requiredLifetime; } // 设置烟花在播放完毕后自动销毁避免堆积 Destroy(newFirework, 5.0f); // 5秒后销毁时间应大于整个特效的持续时间 } } } }脚本逻辑解读射线检测通过ScreenPointToRay将鼠标点击的屏幕坐标转换为一条从摄像机出发的世界空间射线并通过Physics.Raycast检测与场景中物体的碰撞点这个点就是我们要发射烟花的位置。实例化与播放在碰撞点实例化烟花预制体并找到其内部的火箭粒子系统先停止清理可能残留的状态然后调用Play()开始发射。动态参数计算这是脚本的精华。为了让烟花总是在固定的高度launchHeight爆炸我们需要根据火箭的初速度反推它所需的生命周期。公式很简单时间 高度 / 速度。然后通过代码动态修改火箭粒子系统的startLifetime参数。这样无论你在场景的哪个位置点击烟花都能在统一的高度绽放视觉效果更规整。清理机制使用Destroy(gameObject, delayTime)在特效播放完毕后自动销毁实例化的预制体防止游戏对象无限增多导致性能下降。将脚本挂载后在Inspector中将之前创建的Firework_Complete预制体拖拽到fireworkPrefab变量槽中。运行游戏现在用鼠标点击场景中的地面确保地面有Collider组件你就能看到从点击处升空并在固定高度爆炸的烟花了5.2 高级美化技巧颜色、光照与音效基础效果有了我们可以通过一些简单的技巧让它更加惊艳。1. 随机颜色与渐变 不要满足于单一颜色的烟花。我们可以让每次爆炸的颜色都随机。修改Firework_Burst爆炸主体的Start Color属性使用Random Color随机颜色模式或者Random Between Two Gradients在两个渐变间随机。你可以预设几个漂亮的渐变比如从橙到红、从蓝到紫、从绿到黄让系统每次随机选取这样每次点击产生的烟花颜色都不同。2. 添加点光源模拟闪光 真实的烟花爆炸瞬间会照亮周围。我们可以用代码动态添加一个点光源Point Light来模拟。在FireworkLauncher脚本中实例化烟花后可以同时实例化一个预设好的光源预制体或者用new GameObject().AddComponentLight()动态创建。将光源类型设为Point设置一个明亮的颜色可以与烟花颜色匹配调整Range范围和Intensity强度。使用Coroutine协程让光源快速亮起然后衰减消失模拟闪光的瞬间效果。例如IEnumerator FlashLight(Vector3 position, Color color) { GameObject lightObj new GameObject(FlashLight); lightObj.transform.position position; Light flashLight lightObj.AddComponentLight(); flashLight.type LightType.Point; flashLight.color color; flashLight.intensity 5; flashLight.range 10; float duration 0.3f; float elapsed 0; while (elapsed duration) { elapsed Time.deltaTime; float t elapsed / duration; flashLight.intensity Mathf.Lerp(5, 0, t); // 强度从5线性衰减到0 yield return null; } Destroy(lightObj); }在爆炸触发时可以通过粒子系统的OnParticleSystemStopped事件或简单的延时调用启动这个协程。3. 添加音效 音效是氛围的灵魂。准备两个音频片段一个升空的“咻——”声一个爆炸的“嘭”声。在Firework_Rocket和Firework_Burst游戏对象上分别添加Audio Source组件。将对应的音频文件拖入Audio Clip。勾选Play On Awake唤醒时播放可能不合适因为我们是脚本控制播放。更好的方式是在脚本中当播放粒子系统时调用GetComponentAudioSource().PlayOneShot(audioClip);。4. 使用纹理表动画 (Texture Sheet Animation) 让火星粒子不是单调的色块而是有纹理变化的“小星星”。准备一张纹理表Texture Sheet即一张图片上包含多个小火星或光斑的序列帧。在Firework_Burst的粒子系统中勾选Texture Sheet Animation模块。设置Tiles平铺的X和Y值例如如果纹理是4x4的网格就都设为4。将Animation类型设为Whole Sheet整个表系统会自动让粒子在生命周期内播放这个纹理动画。这能让爆炸的火星有闪烁、变化的效果细节大大丰富。6. 常见问题、性能优化与工程管理在实际开发和复现过程中你可能会遇到一些问题。这里我总结了一些常见坑点和优化技巧。6.1 常见问题排查速查表问题现象可能原因解决方案粒子完全不显示1. 材质球Shader不对。2. 粒子发射器被禁用或未播放。3. 粒子大小Start Size为0或极小。4. 粒子寿命Start Lifetime为0。1. 检查材质Shader是否为Particles相关如Additive。2. 检查粒子系统组件是否勾选脚本是否调用了Play()。3. 增大Start Size值。4. 增大Start Lifetime值。拖尾效果不出现1. Trails模块未勾选或参数设置不当。2. 拖尾材质缺失或Shader不对。3. 父粒子速度太快拖尾生命周期太短。1. 确认勾选Trails检查Width over Trail和Color over Trail。2. Trails模块有独立的Material属性需单独指定一个Additive材质。3. 适当增加Trails的Lifetime或降低父粒子速度。子发射器不工作1. 子发射器模块中未正确关联子粒子系统。2. 子粒子系统对象不是父粒子系统的子物体对于Birth等事件。3. 子粒子系统本身有错误如Looping未关闭导致不发射。1. 在Sub Emitters模块中确认事件右侧已拖入正确的粒子系统。2. 将子粒子系统游戏对象拖拽为父粒子系统游戏对象的子级。3. 检查子粒子系统的参数确保其能正常发射如Emission Rate 0。烟花爆炸位置不对1. 火箭粒子的Shape发射半径过大。2. 子发射器Death事件的位置偏移。3. 脚本中计算火箭寿命的逻辑有误。1. 将火箭的Shape半径设为接近0的值如0.01。2. 子发射器位置默认继承父粒子死亡位置通常无需修改。3. 调试脚本打印计算出的requiredLifetime检查launchHeight和rocketSpeed取值是否正确。特效播放一次后无法再次播放1. 粒子系统设置为不循环Loppingfalse且脚本每次实例化新预制体。2. 脚本中未正确清理和重启粒子系统状态。1. 这是正常现象每次点击实例化一个新的即可。确保Destroy延迟时间足够长。2. 在脚本Play()之前先调用Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear)进行重置。6.2 性能优化要点粒子系统虽然强大但过量使用会成为性能杀手尤其是在移动设备上。制作烟花时要注意控制最大粒子数 (Max Particles)这是最重要的参数。为每个粒子系统设置一个合理的上限。例如火箭系统最多10个爆炸系统最多200个拖尾系统最多500个。防止因连续快速发射导致粒子数暴增。简化粒子数量在满足视觉效果的前提下尽可能减少Emission Rate和Burst的粒子数量。50个粒子爆炸效果可能和100个差不多但性能差一倍。使用简单的Shader坚持使用Particles/Additive或Particles/Standard Unlit这类轻量级Shader。避免在粒子材质上使用复杂的StandardShader。合并绘制调用 (Draw Call)如果场景中同时存在多个相同的烟花预制体Unity的动态合批可能无法合批粒子系统。考虑使用对象池 (Object Pooling) 来复用烟花预制体而不是频繁地Instantiate和Destroy。对象池能显著降低GC垃圾回收压力。禁用不可见的系统如果摄像机看不到烟花可以通过脚本 (OnBecameInvisible回调) 或遮挡剔除来停止其粒子发射节省计算资源。6.3 工程文件管理与分享一个整洁的工程结构能让你的工作和分享事半功倍。建议按以下方式组织Assets文件夹Assets/ ├── _Project/ (可选存放项目设置等) ├── Art/ │ ├── Particles/ │ │ ├── Materials/ (存放所有粒子材质如 Particle_Additive.mat) │ │ ├── Textures/ (存放粒子贴图、噪声图、纹理表) │ │ └── Shaders/ (如有自定义粒子Shader) │ └── Audio/ │ ├── SFX_FireworkLaunch.wav │ └── SFX_FireworkExplode.wav ├── Prefabs/ │ └── Firework_Complete.prefab (完整的烟花预制体) ├── Scripts/ │ └── FireworkLauncher.cs └── Scenes/ └── Main.unity当你把工程文件分享给别人时确保包含了所有依赖资源材质、贴图、预制体、脚本和场景。一个常见的错误是只分享了预制体但别人打开后材质是粉色的丢失就是因为材质或贴图没有一同打包。你可以使用Unity的Package Manager窗口中的Export Package...功能勾选所有相关资产导出一个.unitypackage文件这是最可靠的分享方式。最后我把我为这个教程制作的完整Unity工程文件打包好了。里面包含了文中提到的所有粒子系统预设、材质、脚本以及一个演示场景。你导入后可以直接运行点击屏幕放烟花也可以随意拆解、修改里面的参数看看效果会如何变化。真正的学习来自于动手尝试和打破常规。希望这个5分钟就能上手的烟花特效能成为你探索Unity粒子系统庞大世界的一颗火花。