拓冰建站拓冰建站
首页 / 资讯中心 / 正文

UE5金克丝平A特效制作:从Niagara粒子到动画通知

在 UE5 里复现金克丝这类 MOBA 角色的平A特效很多初学者以为最难的是粒子做得足够花真正动手之后才会发现难点在把动画、武器插槽、子弹轨迹、碰撞命中和屏幕反馈串成一条可调试的链路。这篇博客参考何sir演示里那种干脆利落的枪口火花和弹道拖尾风格从零拆解一个金克丝平A特效的落地流程核心内容包含 Niagara 粒子参数、AnimNotify 开火事件、投射物蓝图、命中反馈以及常见坑。学习完这套流程你可以把它套用到其他射击英雄、射击武器或 ARPG 技能的普攻特效里。这里不附任何外部下载地址只讲实现步骤如果你自己制作的粒子、蓝图层和材质需要整理成源文件发给别人第 8 部分会说明哪些内容能分享、怎么整理。1. 金克丝平A特效的组成先拆层再动手直接照着特效视频一帧一帧调粒子大概率会越调越乱。因为视频画面是最终结果不是工程结构。金克丝平A看起来是一个瞬间动作实际上由多层系统共同组成视觉表现、动画触发、子弹逻辑、命中反馈。把这一层拆开后续每个环节都能独立调试。1.1 视觉层三组 Niagara 粒子视觉层至少需要三组粒子枪口火花开火瞬间在枪口位置爆发持续时间短颜色偏亮用来表现火药喷射和光闪。弹道拖尾子弹飞行过程中留下的光带或烟雾路径让玩家能看清子弹从哪个方向飞过来。命中爆裂子弹击中地面或敌人时产生的火花、碎片、闪光用来反馈“这一枪打中了”。这三组效果不应该放在同一个 Niagara System 里一锅炖而是拆成独立资产。原因是它们生命周期不同、挂载位置不同、触发条件不同。枪口火花和命中爆裂属于一次性效果弹道拖尾需要跟随子弹 Actor 移动拆开后能各自循环和释放。1.2 动画层特效必须跟枪口走平A特效不是凭空出现在屏幕上的它必须附着在武器或手臂骨架上。金克丝模型的“枪口”位置通常位于武器模型侧面的炮口。如果在代码里硬编码一个世界坐标角色转头、换动画、换武器后特效位置会全部错位。正确做法是在骨骼网格体上定义一个 Socket动画播放到开火帧时代码从 Socket 拿到世界位置和旋转再生成特效和子弹。这一层的关键是“动画通知”。开火特效必须在动画的某个精确时间点触发否则会出现子弹早已飞出、枪口火花还没出现的问题。1.3 逻辑层子弹是投射物还是射线判定MOBA 平A有两种常见实现方式投射物生成一个子弹 Actor带上碰撞体和 ProjectileMovement按速度飞行碰到目标后触发命中。射线判定从枪口发射一条 LineTrace瞬间计算命中结果只在视觉上生成一条飞行拖尾。金克丝平A视觉上有明显飞行过程适合用投射物来表现。但手感上大型竞技类项目往往使用客户端视觉投射物、服务端即时判定的混合方案。学习阶段先做纯本地投射物跑通链路后再考虑是否拆分逻辑。1.4 复刻顺序建议先做枪口火花再做子弹拖尾然后做命中爆裂最后接动画通知。具体顺序是准备角色、动画、武器 Socket。制作三个 Niagara System。建立子弹 Actor。用 AnimNotify 把动画、特效、子弹串起来。加入震屏、音效和伤害。优化和整理源文件。这个顺序保证每一步都有可见输出不会出现“写了一大堆代码但不知道哪一步错”的情况。2. 环境准备装好 Niagara、配好插槽和碰撞预设2.1 引擎版本与项目模板以下示例基于 UE5.3使用第三人称模板创建空项目。UE5.1 之后 Niagara 已经默认集成但新建项目后仍然建议检查插件状态避免项目模板被裁剪后找不到 Niagara 模块。新建项目时选择 Blank 或 Third Person 都能做。推荐 Third Person因为它自带玩家控制、角色蓝图和输入绑定可以直接复用这些基础设施。如果你手里有金克丝模型和动画暂时不放进去也可以先用小白人角色和一个临时球体子弹验证流程。2.2 插件检查与项目设置打开菜单Edit - Plugins搜索Niagara确认插件处于 Enabled 状态。如果之前某个版本关闭过 Niagara重新启用后需要重启编辑器。在项目设置里关注两项Project Settings - Engine - Collision - Object ChannelsProject Settings - Engine - Rendering - Default Settings中的光照和阴影模式Niagara 对项目渲染设置不敏感真要出问题通常是材质 Blend Mode 和半透明排序导致的。2.3 在骨骼网格上添加 Muzzle_SocketSocket 是挂在骨骼上的命名位置。打开金克丝角色的 Skeletal Mesh 资产在动画骨骼树里找到武器所在骨骼通常位于右手骨骼或武器骨架节点上。操作路径打开SK_Jinx骨骼网格体资产。进入 Skeleton Tree 面板。右键选择手部骨骼或武器节点。选择Add Socket。命名Muzzle_Socket。调整位置把 Socket 移动到枪口前方。调整旋转让 Socket 的 X 轴指向子弹飞行方向。检查 Socket 是否可用最简单的方法是打开动画预览选中Muzzle_Socket转动视角确认三轴方向。如果 X 轴方向错误后面子弹飞行的方向也会跟着错。2.4 子弹的 Object Channel 和碰撞预设子弹碰撞要区分敌人、地面、墙壁和发射者。这里推荐新建一个自定义 Object Channel。在Project Settings - Engine - Collision - Object Channels中新增Object Channel默认响应DamageableBlock然后创建碰撞预设可以基于已有的 Projectile 预设复制再调整响应。碰撞对象响应WorldStaticBlockWorldDynamicBlockPawnBlockDamageableBlockIgnore Owner通过蓝图忽略实际项目中Ignore Owner不一定能直接在预设里配置需要在子弹生成后调用IgnoreActorWhenMoving忽略角色自身。2.5 测试地图和测试 Actor在场景里放置一个静态网格体作为靶子比如 Cube再把靶子的碰撞预设设置为默认 Block。后续所有命中验证都可以打这个靶子。如果是学习环境不要一开始就追求高精度模型。临时用一个球体SM_Sphere当子弹用 Cube 当敌人先把链路跑通。3. 制作三组 Niagara 特效Niagara 在 UE5 里默认使用图表编辑。下面是三组特效的配置思路参数可以根据手感微调。3.1 NS_MuzzleFlash枪口火花新建 Niagara System选择From Selected Emitter任意选一个 Sprite 模板然后把发射器改造成一次性火花效果。关键模块和参数模块/属性设置作用Emitter StateLoop Behavior 设置为 OnceAuto Destroy 开启一次性效果播完自动销毁Spawn Burst InstantaneousSpawn Count 设置为 6一帧内喷出多个火花点Particle Lifetimes0.05 到 0.12 秒火花存在时间极短Initialize ParticleColor 在黄白随机Size 在 12 到 25 随机模拟枪口爆闪Sprite RendererMaterial 使用 M_AdditiveBaseAlignment 使用 Camera Facing让光斑始终面向相机枪口火花不需要物理碰撞。速度可以给一个沿枪口前方的小锥形速度但不要太大否则火花会飞得满屏都是。3.2 NS_Tracer弹道拖尾弹道拖尾有两种做法一种是挂在子弹 Actor 上持续产生粒子一种是纯视觉模拟一条直线。推荐第一种更贴合投射物逻辑。新建 Niagara System发射器配置模块/属性设置作用Emitter StateLoop Behavior 设置为 Infinite子弹存活期间持续生成Spawn Per SecondRate 设置为 100 到 200每秒生成足够多的拖尾粒子Particle Lifetimes0.2 到 0.3 秒拖尾快速消失Ribbon RendererWidth 设置为 3 到 6通过 Ribbon 连接粒子形成光带Ribbon 会将同发射器中按顺序生成的粒子连接成带。如果一帧内批量生成大量粒子Ribbon 会变成一堆断点。要让拖尾连续使用Spawn Per Second而不是一次性 Burst。把这个 Niagara System 挂载到BP_JinxBullet的 Niagara Component 上子弹移动时系统会在世界空间留下拖尾路径。3.3 NS_Impact命中爆裂命中爆裂是一次性发射器参数比枪口火花更剧烈模块/属性设置作用Emitter StateLoop Behavior 设置为 OnceAuto Destroy 开启命中后自动销毁Spawn Burst InstantaneousSpawn Count 设置为 30制造爆发感Particle Lifetimes0.2 到 0.5 秒根据效果需要调整Initialize Particle颜色使用金色或角色主题色适配英雄特效风格Particle Update添加重力或阻力火花向外扩散后自然减速命中效果应该比枪口火花面积更大但单粒子尺寸不要太大。一个常见错误是把粒子尺寸调得很大导致命中点变成一团光斑完全看不清打击点。3.4 特效材质要点Niagara 的特效材质建议单独做一个基础材质材质属性设置Material DomainSurfaceBlend ModeAdditiveShading ModelUnlit最终颜色Texture Sample 乘以 Particle Color是否接收阴影关闭材质节点顺序采样径向渐变贴图。与 Particle Color 相乘。输出到 Emissive Color。Additive 模式适合枪口火花、拖尾和命中闪光因为颜色叠加后会有通透的发光感。缺点是不适合表达烟尘、液体等不透明内容遇到烟雾类效果需要单独做 Translucent 材质。4. 用 AnimNotify 把开火帧和特效、子弹串起来现在粒子资产已经做好但还没有触发源。这一步要做的是在动画播放到开火帧时同时执行三个动作生成枪口火花、生成子弹、播放音效。4.1 创建 AnimNotify_Fire 事件在动画资产或 Animation Montage 的 Notify Track 上右键选择Add Notify然后选择New Blueprint创建名为AN_AnimNotify_Fire的 AnimNotify 蓝图。一个 AnimNotify 对应一次瞬间事件适合普攻开火这种“只触发一次”的逻辑。如果是持续喷射比如加特林转管应该使用 AnimNotifyState。4.2 蓝图版开火事件实现在AN_AnimNotify_Fire的 Event Notify 节点中按下面顺序连线Event Notify (MeshComp, Animation) MeshComp - Get Socket Location(Muzzle_Socket) - SocketLocation MeshComp - Get Socket Rotation(Muzzle_Socket) - SocketRotation Spawn Niagara System at Location Niagara System Asset NS_MuzzleFlash Location SocketLocation Rotation SocketRotation Auto Destroy true SpawnActor BP_JinxBullet Class BP_JinxBullet Location SocketLocation Rotation SocketRotation Owner MeshComp.GetOwner()关键点在于Owner。子弹生成时把 Owner 设置为开火角色碰撞逻辑里才能忽略自己。如果不设置 Owner子弹生成后可能立刻撞上角色的胶囊体。4.3 C 版 AnimNotify 参考项目如果走 C 路线可以创建UAnimNotify_Fire。头文件示例#pragma once #include CoreMinimal.h #include Animation/AnimNotifies/AnimNotify.h #include AnimNotify_Fire.generated.h UCLASS(meta (DisplayName JinxFire)) class JINXFX_API UAnimNotify_Fire : public UAnimNotify { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadWrite) class UNiagaraSystem* MuzzleFX; UPROPERTY(EditAnywhere, BlueprintReadWrite) TSubclassOfAActor BulletClass; virtual void Notify( USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override; };C 实现#include AnimNotify_Fire.h #include NiagaraFunctionLibrary.h #include NiagaraSystem.h #include Components/SkeletalMeshComponent.h void UAnimNotify_Fire::Notify( USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) { if (!MeshComp || !MeshComp-GetWorld()) { return; } const FName SocketName TEXT(Muzzle_Socket); const FVector Location MeshComp-GetSocketLocation(SocketName); const FRotator Rotation MeshComp-GetSocketRotation(SocketName); if (MuzzleFX) { UNiagaraFunctionLibrary::SpawnSystemAtLocation( MeshComp-GetWorld(), MuzzleFX, Location, Rotation ); } if (BulletClass) { FActorSpawnParameters SpawnParams; SpawnParams.Owner MeshComp-GetOwner(); SpawnParams.Instigator CastAPawn(MeshComp-GetOwner()); MeshComp-GetWorld()-SpawnActorAActor( BulletClass, Location, Rotation, SpawnParams ); } }C 版的好处是参数可以配置到 Notify 资产上美术同学在动画时间轴上可以给不同动画指定不同特效和子弹类型。4.4 在 Animation Montage 中放置 Notify创建 Animation Montage把金克丝的普攻 Animation Sequence 放到 Montage 中然后在时间轴上把AN_AnimNotify_Fire放到子弹离开枪口的那一帧。如果你是手动临时测试可以先用一个极短的动画比如 0.3 秒的假动作。开火帧不要放在最后一帧否则动画还没播完角色已经恢复待机姿势视觉上会很奇怪。4.5 检查点在动画预览中看到特效在动画蓝图或动画预览里直接播放包含 Notify 的 Montage如果特效和子弹从正确的 Socket 位置生成说明第 4 步成功。如果动画预览里没有生成特效最常见原因有两个Notify 没有放到实际播放的 Montage 中。AnimNotify 蓝图里引用 Niagra System 的变量没有赋值。先检查这两点再排查其他问题。5. 子弹飞行、碰撞和命中反馈5.1 BP_JinxBullet 的组件结构新建 Actor 蓝图BP_JinxBullet组件层级如下BP_JinxBullet (Actor) SceneRoot (Scene Component) SphereCollision (Sphere Collision) NiagaraComponent (NS_Tracer) ProjectileMovement (Projectile Movement) StaticMesh (可选用于调试)SphereCollision 负责物理碰撞ProjectileMovement 负责飞行NiagaraComponent 负责拖尾。学习阶段可以保留 StaticMesh 显示一个球体便于观察子弹位置。5.2 ProjectileMovement 参数ProjectileMovement 是 UE 内置组件适合快速实现投掷物和子弹飞行。属性推荐值说明Initial Speed2200弹道速度可根据武器手感调整Max Speed2200最大速度避免被加速系统无限提升Projectile Gravity Scale0子弹一般不受重力影响bRotationFollowsVelocitytrue让子弹模型头部朝飞行方向bUseCCDtrue开启连续碰撞检测避免高速穿透InitialSpeed 设置在 BP 中暴露为变量方便不同武器复用高速子弹最典型的问题是隧穿子弹速度太快两帧之间跨越了碰撞体的厚度导致没触发碰撞。开启bUseCCD能在多数简单场景中解决这个问题。5.3 碰撞命中事件区分对象在BP_JinxBullet中给 SphereCollision 添加OnComponentHit事件。命中事件的处理逻辑先判断 Hit Actor 是否为空。再判断是否命中 Owner 或角色自身。如果是可伤害对象生成NS_Impact。调用ApplyDamage或自定义伤害接口。播放相机震动。Destroy 子弹或回收进对象池。蓝图事件顺序Event OnComponentHit (HitComp, OtherComp, OtherActor, NormalImpulse, HitResult) if OtherActor Owner - return if OtherActor null - return Spawn Niagara System at Location Asset NS_Impact Location HitResult.Location Rotation HitResult.Normal.Rotation() UKismetSystemLibrary::ApplyDamage DamagedActor OtherActor Damage BaseDamage EventInstigator Instigator DamageCauser Self Play Camera Shake Destroy Actor命中旋转建议使用HitResult.Normal方向这样火花会从表面向外喷而不是朝固定方向。5.4 命中反馈Niagara、伤害、相机震动命中反馈决定了一次射击是否“重”。如果子弹飞过去只留下一个点玩家会觉得自己在打空气。反馈至少包含三层视觉命中点火花、受击者身上的闪光。逻辑扣血、击退、受击动画。屏幕CameraShake、准星变化、音效。金克丝的风格适合把命中火花做得偏“爆”粒子数量不用多但速度要快、扩散角度要大。相机震动不要给太大否则连续射击时画面会晃到看不清。5.5 子弹生命周期和对象池学习阶段可以在命中后直接Destroy Actor。生产环境不建议每枪都 SpawnActor 和 Destroy因为频繁创建销毁会打 GC遇到团战大量平A时会卡顿。生产环境做法预生成一批子弹 Actor。开火时从对象池中取一个。命中或超时后隐藏并回到池中。同一时间最多存在 20 颗左右子弹。对象池同时解决了 NiagaraComponent 反复创建销毁的问题拖尾特效也会更稳定。6. 运行验证从一次普攻到完整命中链路6.1 一次手工普攻的验证步骤把角色放进测试地图运行游戏按下普通攻击键按这条链路观察角色是否播放攻击 Montage。开火帧上是否出现枪口火花。是否生成子弹 Actor。子弹是否沿枪口方向飞向目标。子弹命中后是否出现命中爆裂。目标是否扣血。屏幕是否有轻微震动。任何一环断掉就回到那一步去查。不要同时改多个系统后再启动否则分不清问题来自哪里。6.2 验证用的 Log 和屏幕打印在蓝图里临时加入Print String方便快速确认事件触发顺序[Notify] Fire at socket location. [Bullet] Spawned bullet, velocity ... [Hit] HitActor BP_Target, location ...建议在四打印点各加一条。正常顺序应该是Notify Fire Bullet Spawned Hit Actor Impact Spawned如果Notify Fire没出来说明动画通知没触发。如果Bullet Spawned没出来说明 SpawnActor 失败检查子弹类是否设置正确。6.3 用 Stat 命令观察 Niagara 性能运行游戏时在控制台输入stat niagara相关命令可以看到实例数、粒子数、提交Draw Call等信息。不同 UE5 小版本命令名可能略有差异但核心是观察粒子的实例数和总粒子数。如果你的场景里只有一颗子弹粒子数却在几千说明发射器每秒生成太多粒子或者粒子寿命太长。对比值可以看枪口
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门