UE5 动态天气系统:雨、雪、雾的 Niagara 实现方案
上周有位学员在课后问我:“老师,我照着教程做了个雨滴粒子,但一进入游戏场景就穿模,而且下雨时地面根本没反应,这怎么解决?”这个问题非常典型——许多开发者用 Niagara 做天气时,只关注粒子本身,忽略了环境交互和性能优化。今天我们就从零开始,用 UE5.3 的 Niagara 系统,实现一套完整的动态天气系统,包括雨、雪、雾三种核心效果,并解决穿模、性能、环境反馈等实际问题。
一、雨滴系统:从粒子到环境交互
1.1 基础雨滴粒子
打开 Niagara System,选择 “New Niagara System” → “Simple CPU Sprite”。这里我强烈建议用 CPU 而非 GPU 粒子,因为后期我们需要对每个粒子进行碰撞检测,CPU 模式更易控制。
关键参数设置:
- Spawn Rate:1000-2000 粒子/秒(根据场景大小调整)
在 Particle Spawn 模块中,添加 “Scale Color” 节点,将 Alpha 通道设为 0.6-0.8,让雨滴半透明。同时启用 “Camera Offset”,让粒子始终面向摄像机——这是避免雨滴穿模的关键!具体操作:在 Render 模块的 Sprite Renderer 中,将 Alignment 设为 “Screen Alignment”,并勾选 “Lock Axis” 为 Z。
1.2 地面碰撞与涟漪
这是解决学员问题的核心。在 Particle Update 模块中添加 “Collision” 节点:
当粒子碰撞地面后,我们需要触发涟漪。新建一个 Event Handler,在 Particle State 模块中,将 “On Collision” 事件绑定到 “Spawn Burst” 动作。这个动作会在地面位置生成子粒子(涟漪)。
涟漪粒子设置:
1.3 雨滴与角色的交互
为了让雨滴在角色身上产生效果,我们需要在角色骨骼上添加 “Niagara Component”。在角色的蓝图(BP_Character)中,添加一个 “Niagara Particle System Component”,引用刚才的雨滴系统。然后在 Event Tick 中更新粒子的位置,使其跟随角色移动。
优化技巧:当角色在室内时,通过 “Visibility Based Complete” 参数关闭粒子系统,避免性能浪费。具体实现:在角色蓝图中,用 “Line Trace” 检测角色头顶是否有遮挡物,如果检测到遮挡,则调用 “Set Visibility” 为 false。
二、降雪系统:体积感与堆积效果
2.1 雪花粒子的体积散射
雪花比雨滴更轻、更慢,需要表现出飘落的随机性。创建新的 Niagara 系统,选择 “Simple CPU Sprite”。
参数调整:
关键是要模拟雪花的“翻滚”效果。在 Particle Update 模块中添加 “Vortex Force” 节点:
2.2 地面积雪的动态生成
雪花落地后不应该消失,而是逐渐堆积。这需要用到 “Render Target” 技术。在场景中放置一个 “Decal Actor”,绑定一个 “Material Instance”,该材质使用 “Landscape Mask” 和 “Snow Height” 参数。
实现步骤:
1. 在 Niagara 系统中,当雪花粒子碰撞地面时,通过 “Spawn Burst” 事件输出碰撞位置。
2. 在关卡蓝图中,用一个 “Array of Vector” 存储这些位置。
3. 每帧读取数组,更新材质中的 “Snow Height” 参数(用 “Set Scalar Parameter” 节点)。
4. 材质中用 “World Position” 与存储位置的距离计算积雪高度。
性能警告:不要每帧更新所有位置!建议每 5 帧采样一次,并且只存储最近 200 个位置。
2.3 性能优化:LOD 与剔除
降雪系统很容易造成性能瓶颈。在 Niagara 的 “System State” 模块中,启用 “LOD”:
同时,在 “Culling” 模块中,勾选 “View Based Culling”,设置 “Max Distance” 为 5000 单位。超出范围的粒子直接不生成。
三、雾效系统:体积雾与动态变化
3.1 基于 Niagara 的体积雾
传统雾效用 “Exponential Height Fog” 就够了,但动态天气需要雾的浓度随时间和天气变化。我们可以用 Niagara 的 “Grid 3D” 模拟体积雾。
创建 “New Niagara System”,选择 “Grid 3D” 模板。在 “Grid” 模块中:
在 “Update” 模块中添加 “Noise” 节点,用 “Perlin Noise” 生成密度场。将噪声值映射到 0-1,控制雾的密度。
3.2 雾的动态变化
在 “Particle Spawn” 模块中,用 “Time” 节点驱动噪声的 “Frequency” 和 “Offset”,让雾缓慢流动。具体:
为了与雨雪联动,在关卡蓝图中添加一个 “Weather Manager” 蓝图。它控制三个 Niagara 系统的 “Activate” 和 “Deactivate”,并通过 “Set Float Parameter” 统一调整雾的密度。
3.3 雾与灯光的交互
体积雾需要配合 “Volumetric Fog” 渲染才能看到效果。在项目设置中:
为了让雾在灯光下更真实,在 Niagara 的 “Render” 模块中,将 “Material” 设为 “M_VolumetricFog”(引擎自带材质),并调整 “Scattering Coefficient” 为 0.3-0.5。
四、总结与进阶建议
这套动态天气系统的核心思路是:用 Niagara 控制粒子行为,用事件系统实现交互,用材质和渲染目标反馈环境。雨、雪、雾三种效果可以独立运行,也可以通过 Weather Manager 无缝切换。
进阶方向:
1. 声音系统:用 “Audio Component” 配合粒子事件,下雨时播放雨声,雪天切换为静音。
2. 风场系统:用 “Vector Field” 或 “Wind Directional Source” 影响所有粒子运动。
3. 动态时间:用 “Time of Day” 蓝图控制雾的颜色(白天淡蓝,夜晚灰黑)。
4. 性能监控:在编辑器中打开 “Niagara Debugger”,观察粒子数量和碰撞开销。
最后提醒:不要贪多!先从一个效果(比如雨滴)做到完��,再叠加其他效果。很多学员失败是因为一次性塞入太多功能,导致调试困难。
常见问题 FAQ
Q1:雨滴粒子穿模到建筑物内部怎么办?
A1:除了启用 Camera Offset,还可以在碰撞模块中设置 “Collision Channel” 为 “WorldStatic”,并确保建筑物有 “Block” 碰撞体。如果仍有穿模,在粒子更新中添加 “Trace” 节点,检测前方是否有障碍物。
Q2:雪花堆积效果导致帧率骤降,如何优化?
A2:限制存储位置的数量(最多 300 个),并降低 Render Target 的更新频率(每 10 帧更新一次)。另外,将雪花的碰撞检测改为 “Simple” 模式,不要用 “Complex”。
Q3:雾效在移动端看不到,怎么办?
A3:移动端不支持 Volumetric Fog。替代方案:用 “Particle Sprite” 模拟雾,生成大量半透明、大小随机的粒子,并禁用光照。性能会好很多。
Q4:如何让天气系统在关卡之间保持状态?
A4:将 Weather Manager 设为 “Game Instance” 的子对象,用 “Save Game” 保存当前天气类型和参数。加载新关卡时,从 Game Instance 读取并恢复。
Q5:雨滴溅到角色身上时,涟漪只能在原地出现,不能跟随角色?
A5:这是因为涟漪粒子是在世界空间生成的。解决方法:在角色蓝图中,用 “Attach Niagara Component” 将子粒子系统绑定到角色骨骼,并在碰撞事件中传递相对位置。

评论(0)