UE5 动态天气系统:雨、雪、雾的 Niagara 实现方案

上周有位学员在课后问我:“老师,我照着教程做了个雨滴粒子,但一进入游戏场景就穿模,而且下雨时地面根本没反应,这怎么解决?”这个问题非常典型——许多开发者用 Niagara 做天气时,只关注粒子本身,忽略了环境交互和性能优化。今天我们就从零开始,用 UE5.3 的 Niagara 系统,实现一套完整的动态天气系统,包括雨、雪、雾三种核心效果,并解决穿模、性能、环境反馈等实际问题。

一、雨滴系统:从粒子到环境交互

1.1 基础雨滴粒子

打开 Niagara System,选择 “New Niagara System”“Simple CPU Sprite”。这里我强烈建议用 CPU 而非 GPU 粒子,因为后期我们需要对每个粒子进行碰撞检测,CPU 模式更易控制。

关键参数设置

  • Spawn Rate:1000-2000 粒子/秒(根据场景大小调整)
  • Lifetime:0.8-1.2 秒(随机分布)
  • Initial Velocity:X: 0, Y: 0, Z: -800 ~ -1200(模拟重力加速度)
  • Sprite Size:宽度 0.3,长度 1.5(模拟雨滴拉长效果)
  • 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” 节点:

  • Collision Mode“Surface Only”(仅碰撞地面)
  • Restitution:0.0(完全停止)
  • Friction:0.5
  • 当粒子碰撞地面后,我们需要触发涟漪。新建一个 Event Handler,在 Particle State 模块中,将 “On Collision” 事件绑定到 “Spawn Burst” 动作。这个动作会在地面位置生成子粒子(涟漪)。

    涟漪粒子设置

  • Spawn Rate:1(每次碰撞生成一个)
  • Lifetime:0.3-0.5秒
  • Initial Velocity:全部为0
  • Sprite Size:从 0.2 线性增长到 1.0(使用 “Scale Sprite Size” 节点,配合 “Normalized Age” 驱动)
  • Color:Alpha 从 0.5 衰减到 0
  • 雨滴碰撞涟漪效果

    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”

    参数调整

  • Spawn Rate:500-800 粒子/秒
  • Lifetime:3-5秒
  • Initial Velocity:X: -50~50(随机水平飘动),Y: -50~50,Z: -200~-300
  • Sprite Size:0.5-1.0(圆形,用 “Texture” 加载雪花贴图)
  • 关键是要模拟雪花的“翻滚”效果。在 Particle Update 模块中添加 “Vortex Force” 节点:

  • Vortex Strength:20-50
  • Vortex Axis:随机方向(用 “Random Vector” 节点)
  • Noise Strength:10-30(增加随机扰动)
  • 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”

  • LOD0:完整效果(近距)
  • LOD1:粒子数量减半,关闭 Vortex Force(中距)
  • LOD2:仅保留 10% 粒子,关闭碰撞(远距)
  • 同时,在 “Culling” 模块中,勾选 “View Based Culling”,设置 “Max Distance” 为 5000 单位。超出范围的粒子直接不生成。

    三、雾效系统:体积雾与动态变化

    3.1 基于 Niagara 的体积雾

    传统雾效用 “Exponential Height Fog” 就够了,但动态天气需要雾的浓度随时间和天气变化。我们可以用 Niagara 的 “Grid 3D” 模拟体积雾。

    创建 “New Niagara System”,选择 “Grid 3D” 模板。在 “Grid” 模块中:

  • Grid Resolution:32x32x16(根据性能调整)
  • Grid Size:5000x5000x1000(覆盖场景范围)
  • “Update” 模块中添加 “Noise” 节点,用 “Perlin Noise” 生成密度场。将噪声值映射到 0-1,控制雾的密度。

    3.2 雾的动态变化

    “Particle Spawn” 模块中,用 “Time” 节点驱动噪声的 “Frequency”“Offset”,让雾缓慢流动。具体:

  • Frequency:0.01-0.05(随时间缓慢变化)
  • Offset:用 “Sine Wave” 节点,周期 10-30 秒
  • 为了与雨雪联动,在关卡蓝图中添加一个 “Weather Manager” 蓝图。它控制三个 Niagara 系统的 “Activate”“Deactivate”,并通过 “Set Float Parameter” 统一调整雾的密度。

    3.3 雾与灯光的交互

    体积雾需要配合 “Volumetric Fog” 渲染才能看到效果。在项目设置中:

  • RenderingVolumetric Fog:勾选 “Volumetric Fog”
  • Light:使用 “Directional Light” 并启用 “Volumetric Scattering”
  • 为了让雾在灯光下更真实,在 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” 将子粒子系统绑定到角色骨骼,并在碰撞事件中传递相对位置。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。