公司动态

UE5近战攻击蓝图系统详解:从输入到伤害结算的完整实现

📅 2026/9/2 21:50:05
UE5近战攻击蓝图系统详解:从输入到伤害结算的完整实现
这次我们来看一套非常典型的 UE5 近战攻击蓝图逻辑BP_SystemAttack。这套系统在《UE5 虚幻入门到就业》系列课第 215 集18.5.3里做了完整拆解主题方向是“近战平A”。简单说它解决的是角色在场景里按下攻击键之后如何正确播放攻击动画、命中判定、伤害结算、连击切换这一整套逻辑。这篇文章会按照蓝图模块拆开讲一遍从输入触发到动画通知再到伤害检测和特效反馈尽量把上篇里涉及的核心节点和设计思路讲清楚。如果你正在学 UE5 蓝图已经会做角色移动和基础交互但一直卡在“攻击逻辑”这一块这篇文章可以直接当作学习笔记用。下面内容不是把视频字幕搬过来而是把蓝图里每个模块做成可理解、可调试的技术知识点。因为这一集是上篇所以重点会放在“普通攻击”而不是技能、霸体、受击反馈这些扩展内容。1. 核心能力速览BP_SystemAttack本质上是一个角色蓝图内的攻击逻辑子系统可以挂在 Character 蓝图里也可以做成独立的 Actor Component方便复用。从课程拆解来看它至少包含这些模块能力项说明系统类型角色近战平A攻击蓝图逻辑运行环境UE5 蓝图可视化脚本前置逻辑角色移动、动画蓝图、动画 Montage核心功能攻击输入触发、Montage 播放、连击段数控制、动画通知、命中检测、伤害结算、特效反馈命中检测方式动画通知配合碰撞检测或 Sweep/Overlap具体按项目需要切换伤害结算通过 Apply Damage 或自定义事件分发器传给目标扩展接口事件分发器Event Dispatcher、蓝图接口Blueprint Interface是否支持 Niagara支持武器拖尾、命中特效、受击特效都可以在动画通知里生成适合场景近战角色、怪物攻击、玩家普通攻击、连招逻辑从课程编号看这是入门到就业系列里的第 215 集说明前面的课程应该已经讲过角色蓝图、动画通知、Montage 播放、Niagara 基础这些前置内容。如果你还不会这些建议先补一下。2. 适用场景与使用边界BP_SystemAttack这种系统的典型使用场景是第三人称动作游戏、近战角色普攻、怪物攻击逻辑、或者你正在做的独立游戏原型。它解决的核心问题有两个第一是攻击状态的管理防止攻击期间重复触发造成动画错乱第二是攻击命中的判定时机也就是动画播到哪一帧才算“砍到人”。它不适合做什么不太适合做远程投射物、复杂技能组合、多段霸体、受击取消这类高级战斗系统。这些不是做不了而是上篇的逻辑还停留在“普通攻击框架”后面需要继续扩展行为树、技能冷却、Buff 系统等。从使用边界来说如果你是做商业项目建议把攻击逻辑尽快从角色蓝图里拆到独立 Actor Component 或 C 类中否则角色蓝图会越来越臃肿。这也是课程里会强调工程化思维的原因。安全合规方面如果项目使用了他人的动画资产、音效、Niagara 特效素材要注意授权范围尤其是用于商业发布时要确认素材许可。涉及到角色形象、动作捕捉数据时也应确认来源合法。3. 环境准备与前置条件开始之前先确认你的开发环境。UE5 系列课程一般会指定一个版本比如 UE5.0、UE5.1 或 UE5.3不同版本的蓝图节点在命名上有细微差别但整体逻辑一致。建议直接使用课程配套版本避免节点找不到。需要准备的内容项目说明虚幻引擎UE5.x 任一稳定版建议与课程版本一致角色模型带武器骨骼的骨骼网格体或创建 Cubeguy 测试角色动画资产待机、攻击1、攻击2、攻击3 等 Montage 片段输入映射Enhanced Input 或旧版 Input Axis配置攻击键Niagara 资产武器拖尾、命中特效、受击特效可先用占位资产网络场景一个测试地图地面、墙壁、几个测试目标如果你的动画资产上是“攻击 Montage 帧数不同步”的问题后面测试时会很难判断是逻辑问题还是动画问题。建议第一步先创建一套测试动画比如三段攻击每段 0.7 秒到 1 秒动画通知统一放在“武器挥到最前方”的帧位置。磁盘空间方面UE5 安装本身已经占比较大了如果还要生成 Niagara 缓存和烘焙光照建议预留 100 GB 以上空闲空间。显卡和内存按 UE5 编辑器正常要求即可大场景不建议在低配机器上频繁测试。4. BP_SystemAttack 蓝图总体设计先理清整体结构。攻击逻辑最容易踩的坑是所有节点挤在角色蓝图里看起来能跑但过两周自己都看不懂。所以课程在讲逻辑之前一定会在脑中把攻击拆成四个阶段4.1 触发阶段玩家按下攻击键输入系统检测到后先判断角色当前是否允许攻击。允许攻击是一个括号问题当前是否正在播放攻击 Montage当前是否处于受击状态当前是否在移动中如果都允许就进入下一阶段。4.2 表现阶段角色播放对应段数的攻击 Montage。这里的核心不是 Play Montage 节点本身而是“段数选择”第一次按是攻击一第二次按是攻击二第三次按是攻击三之后回到攻击一。4.3 判定阶段动画播到攻击帧时动画通知Anim Notify通知蓝图开始做命中检测。检测时机比检测实现更重要。常见做法是 Sphere Overlap 或 Sweep Single By Channel从角色前方扇形区域检测敌人。4.4 结算阶段检测到目标后通过 Apply Damage 或自定义事件把伤害值、来源、武器类型等参数传给目标。目标再处理自己的受伤响应。上篇课程最核心的就是把这四个阶段用蓝图节点串起来并且保证“连击”时状态不冲突。4.5 蓝图结构与命名建议如果 BP_SystemAttack 是一个独立 Actor Component它应该有变量名类型作用AttackIndexInteger当前攻击段数1/2/3bIsAttackingBoolean是否处于攻击状态bCanNextComboBoolean是否允许下一段连击AttackMontageArrayArray三段攻击动画DamageValueFloat攻击伤害值AttackRangeFloat攻击检测距离AttackRadiusFloat攻击检测半径TargetActorActor当前检测目标这些变量不一定都出现在上篇但它们是整个 BP_SystemAttack 的基础数据结构。变量命名规范非常重要UE5 蓝图命名建议使用b前缀表示布尔值数组用复数命名这样在蓝图节点搜索时不容易看混。5. 核心逻辑编写从输入到动画播放下面把攻击逻辑按节点层级拆开。因为这是上篇我们重点看“按下攻击键 → 播放对应攻击蒙太奇 → 切换到攻击状态”这条主链。5.1 输入触发使用 Enhanced Input 时可以在角色蓝图里绑定IA_Attack动作。调用事件后先写一个CanAttack分支条件。核心判断逻辑角色控制器是否有效bIsAttacking是否为 false角色当前是否在地面如果是空中攻击则需要额外判断Anim Instance 里是否正在播放攻击 Montage这些条件用 Branch 连起来时建议用AND逻辑而不是多个 Branch 嵌套否则蓝图会很乱。可以创建一个IsCanAttack函数把所有条件放在一起返回一个 Boolean。代码块示意这里是蓝图节点逻辑的伪代码用来帮助理解不是 C 代码Event AttackInput - Call Func IsCanAttack - Branch (Result) - True: if bIsAttacking false: bIsAttacking true AttackIndex 1 Play Montage (AttackMontageArray[0]) - False: Cancel or Ignore这个逻辑的关键是第一次按下时bIsAttacking从 false 变 true同时开始播放第一段 Montage。攻击期间所有新的输入都进入“连击缓存”而不是直接播放新动画。5.2 连击输入缓存上篇常见的做法是设置一个bCanNextCombo变量动画通知里在攻击后段打开这个开关。连击流程是动画播到 60% 时发出AnimNotify_ComboWindowStart此时如果玩家再次按攻击键就把AttackIndex加 1然后播放下一段 Montage动画播完时发出AnimNotify_ComboWindowEnd此时再按攻击键不再切段这样做的好处是玩家快速连点三次攻击键角色会在第一段动画接近尾声时平滑切换到第二段而不是每一段都从头播放。手感会好很多。如果bCanNextCombo一直为 false那连击永远不会触发。这个变量是连击逻辑的开关排查时先看它有没有被动画通知正确置位。5.3 动画 Montage 播放Play Montage 节点有返回值其中Montage Instance可以拿到当前正在播放的 Montage。播放前要绑定两个重要回调On Montage StartedOn Montage EndedOn Montage InterruptedOn Montage Completed结束回调里最重要的一步是bIsAttacking falsebCanNextCombo false然后把AttackIndex重置为 1。很多新手会漏掉这个重置导致角色攻击完一次后AttackIndex还是 2下一次按攻击键直接从第二段开始看起来就是乱招。代码块示意On Montage Ended (AnimMontage) bIsAttacking false bCanNextCombo false AttackIndex 1这也是为什么“攻击结束后还原状态”是这个系统的核心稳定点。只有把这段写死了连击和普攻才能循环使用。6. 动画通知与伤害检测动画通知是攻击逻辑中最容易出错也最能体现工程水平的地方。原理很简单动画播放到特定帧时通知蓝图执行逻辑。执行的内容要与动画表现同步也就是“手挥出去了伤害才触发”。6.1 创建动画通知在攻击 Montage 里找到“武器挥到最前方”的帧添加一个AnimNotify_AttackHit再在攻击后段添加AnimNotify_ComboWindowStart和AnimNotify_ComboWindowEnd。这些通知会在 Anim Blueprint 或 Character Blueprint 中触发事件。课程中的大概率逻辑是角色蓝图里监听这些通知在AttackHit通知里做检测在ComboWindowStart里开放连击窗口。AnimNotify_AttackHit的执行时机很关键太早会让武器还没碰到敌人就造成伤害太晚会出现穿模和命中延迟。正确做法是反复观察动画调整通知所在帧。6.2 命中检测实现命中检测最常用的是Sphere Overlap Actors节点。你可以把武器的世界位置作为检测原点检测半径设为武器长度然后过滤掉自己、友军、不可伤害物体。核心节点Sphere Overlap ActorsGet Actor Location武器槽位 Socket 位置Damage ValueApply Damage筛选目标时建议通过Is A或 Actor Tag 来过滤。不要在 Overlap 节点里直接对所有检测到的 Actor 造成伤害因为检测结果可能包含地面、墙壁、特效发射器。正确做法是先 Overlap得到数组再遍历数组在遍历中对目标做类型判断再调用伤害接口。代码块示意ArrayAActor OutActors Sphere Overlap Actors (CenterWeaponSocketLocation, RadiusAttackRange) - For Each Loop (OutActors) - Branch (Target has Damage Interface) - True: Apply Damage(Target, DamageValue)这里如果是用接口判断建议使用自定义接口IDamageable或BPI_CombatInterface。这样后续怪物、NPC、玩家都能统一实现受伤行为不需要为每一个目标类型写单独分支。6.3 动画通知里不能写太多逻辑动画通知是事件驱动不应该在里面把整套攻击结算都写完。通知里可以调用角色蓝图的一个函数比如PerformAttackHit动画通知只负责“告诉蓝图该判定了”具体判定逻辑放在函数里。这样做的优点调试的时候方便打断点也可以在控制台打日志后续如果要做远程攻击、投射物、群攻只需要替换PerformAttackHit内部实现动画通知不需要动。7. 视觉反馈与 Niagara 扩展这套系统里引入 Niagara 是自然的。攻击时如果只有动画没有特效打击感会差很多。Niagara 在这个系统里至少有三个接入点。7.1 武器拖尾用 Niagara 做一个简单的拖尾系统在攻击动画开始时激活在攻击结束或动画通知处关闭。控制方式有两种一种是在动画通知里 Spawn System at Location另一种是直接在角色武器骨骼上挂一个 Niagara 组件在攻击时激活。推荐第二种因为拖尾要跟随武器骨骼移动如果用 Spawn System 还需要每帧设置位置比较麻烦。挂组件的做法是把 Niagara 组件附加到武器 Socket默认关闭自动激活攻击开始时激活组件攻击结束时停用组件7.2 命中特效命中特效一般放在PerformAttackHit函数里检测到目标后在目标位置生成一次性的 Niagara 系统。这个适合用Spawn System at Location因为特效是一次性的不需要跟随目标很久。7.3 受击反馈受击逻辑通常在目标身上实现但攻击蓝图需要给目标传递一个值。比如可以通过Apply Damage的默认参数传递伤害类型目标蓝图收到后播放受击动画和受击特效。这部分一般不会在上篇展开但框架上要预留好。7.4 特效与逻辑分离特效只负责表现不参与伤害计算。伤害计算要在检测逻辑里完成。这样做的好处是即使特效没加载出来攻击和伤害结算还是正常的不会出现“看不到特效就打不出伤害”的隐蔽问题。8. 功能测试与效果验证攻击逻辑写完之后不要急着堆特效先把基础功能在测试场景里验证一遍。下面给出一套标准的验证流程。8.1 测试环境和准备新建一个第三人称测试关卡放置一个测试目标。目标建议使用简单的 Cubeguy 或静态网格体并实现Take Damage事件在角色身上显示当前血量或者在屏幕输出伤害值方便确认结果。场景里的地面、墙体、目标要用不同的 Actor 类型这样才能验证 Overlap 之后的过滤逻辑是否正确。8.2 验证点测试项操作预期结果首次攻击空闲时按攻击键角色播放攻击一屏幕输出“Hit”目标血量减少二次连击攻击一后快速按攻击键角色播放攻击二不跳段攻击结束状态连击结束后按攻击键重新从攻击一开始攻击期间打断播放攻击动画时持续按攻击键不会立刻重复播放攻击一命中过滤攻击空气、地面不输出伤害攻击距离站在远处攻击不命中符合 AttackRange状态还原等待完整攻击结束bIsAttacking变 falseAttackIndex 重置8.3 调试方式在角色蓝图里用Print String把关键变量打印出来按下攻击键时打印AttackIndex播放 Montage 时打印Current Montage命中检测时打印命中目标和伤害值结束时打印bIsAttacking如果bIsAttacking一直是 true问题大概率在 Montage 结束回调没有触发。检查 Montage 是否被打断、节点是否被中断。8.4 常见调试命令在 UE5 编辑器中可以在 Output Log 里通过控制台命令观察角色状态showdebug animation这个命令可以看到当前正在播放的动画和 Montage 状态适合检查攻击动画是否切换成功。也可以使用蓝图 Debug 工具在蓝图图表里给关键节点打断点按 F9 进入断点逐帧观察变量变化。9. 资源占用与性能观察攻击逻辑本身的性能开销很小蓝图节点再多也不至于卡顿。真正的开销来自命中检测和 Niagara 特效。9.1 命中检测性能Sphere Overlap 如果用得过于频繁每帧都调用并且范围很大在多人场景下就会明显占用 CPU。建议只在动画通知发生时检测而不是每帧检测。这是攻击逻辑性能优化最重要的一条。9.2 Niagara 性能武器拖尾特效如果粒子数过高或者拖尾时间过长会造成渲染压力。建议拖尾粒子控制在 100 到 300 量级拖尾长度等于攻击挥动长度不要持续太长时间命中特效使用较短的寿命同一个场景中不要同时激活大量命中特效9.3 蓝图性能分析可以在编辑器里使用Stat命令观察性能。常用命令stat game stat unit stat startfilestat startfile会生成性能分析文件用于检查攻击事件触发的耗时。一般来说一次攻击事件里节点数量不超过 50 个就不会有问题。如果你发现攻击时角色顿卡先检查是否在攻击回调里做了大量数据遍历或对象生成。10. 常见问题与排查方法攻击系统是新手最容易卡住的地方下面这些问题是实际开发里出现频率最高的。问题现象可能原因排查方式解决方案按下攻击键没有反应输入映射未配置、角色蓝图未绑定检查 Enhanced Input 资产和事件绑定在角色蓝图里重新绑定 IA_Attack 事件攻击动画播不出来Montage 资产路径错误或动画资源缺失播放时在 Output Log 查看 Montage Instance 是否为空替换为有效的 AnimMontage 并确认骨架匹配播放攻击动画但伤害不触发动画通知帧位置不对或通知类型错误双击 Montage 检查 Notify 位置把 AnimNotify_AttackHit 移到正确帧并添加为 Anim Notify攻击不能连击ComboWindowStart 通知没有触发打印bCanNextCombo的状态在动画通知中确认通知名称拼写一致并确保已添加通知攻击结束后状态未还原On Montage Ended 回调未绑定或逻辑有误打印bIsAttacking绑定 All Montage Instances 的结束回调或逐条绑定攻击时频繁重复触发没有判断bIsAttacking是否允许攻击在入口处打分支先判断bIsAttacking再进入播放逻辑命中检测命中地面和墙壁没有过滤 Actor 类型在遍历后打印 HitActor 类名加上类判断或 Actor Tag 过滤伤害数值不变或为零DamageValue 节点未正确设置在 Apply Damage 前打印 DamageValue初始化变量并为当前武器配置正确的伤害值UE5 编辑器崩溃提示 LowLevelFatalError可能由动画资产或 Niagara 资产损坏导致查看崩溃日志中的资源路径重装或替换对应资源更新显卡驱动连击后从第二段开始AttackIndex 重置时机不对打印 Montage 结束后的 AttackIndex在 Montage 完全结束时将 AttackIndex 重置为 1排查时有一个基本原则每次只改一个变量、只测一种情况。不要在发现问题后同时改五个变量否则你根本不知道是哪一个修复了问题。11. 最佳实践与使用建议11.1 变量命名与注释攻击系统变量比较多建议用以下风格bIsAttacking表示是否在攻击状态AttackIndex表示当前攻击段数AttackMontageArray表示全部攻击动画PerformAttackHit表示执行攻击判定函数每个函数和关键变量都写注释。UE5 蓝图里的注释是Ctrl B函数注释在函数节点上添加。这一点对后期调试非常重要。11.2 把攻击逻辑拆成函数不建议把所有逻辑都写在事件图表里。建议把入口做成几个独立函数函数作用CanAttack判断能否攻击StartAttack开始攻击播放 MontageNextComboAttack连击切换PerformAttackHit执行命中检测和伤害结算EndAttack结束攻击重置状态这样上篇的逻辑就变成了清晰的调用链而不是一长串节点。11.3 预留接口化设计建议定义一个蓝图接口比如BPI_CombatInterface里面包含ReceiveDamage、GetHealth、IsDead等函数。攻击系统只依赖接口不依赖具体目标类型。这样目标可以是敌人、木桩、BOSS只要实现接口就能被攻击。接口的泛用性更强后期扩展也更容易。11.4 动画资产调试如果敌我模型使用同一套骨骼动画复用会很简单。如果骨骼不同需要做重定向。注意在重定向后重新检查攻击 Montage 的动画通知帧位置因为不同骨骼的模型长度和动作节奏可能不一致通知位置很可能会跑偏。11.5 合规与版权提醒项目使用的动画、音效、特效资产需要确认版权。UE 商城、Fab、Mixamo 等不同来源的授权规则不同商用前要逐条确认。如果项目使用了真人动作捕捉数据、真实人物形象还要关注肖像权和数据来源问题。考试学习是没问题但发布作品时要谨慎。12. 总结与下一步BP_SystemAttack的上篇核心并不是某个魔法节点而是“输入触发 → 状态管理 → 动画播放 → 通知回调 → 命中检测”的完整链路。你能把这条链路理顺攻击系统就成功了一大半。最容易踩的坑有两个一个是bIsAttacking没有在 Montage 结束回调里重置导致角色攻击完一次后再也不能攻击另一个是连击开关没有由动画通知打开导致连点攻击键不会切换动作。把这套逻辑写完之后下一步值得继续扩展的方向有几块攻击命中后的受击反馈也就是目标被击中后的动画、位移和特效攻击打断机制比如被敌人击中后强制中断当前攻击Buff 或技能系统在攻击基础上增加冷却时间、SP 消耗、技能范围等参数。如果课程后续讲下篇大概率会把范围伤害、多段判定、打击停顿这类进阶内容补上。建议你在学下一集之前先把上篇这套逻辑练成肌肉记忆能不看笔记从零画出攻击主链再进入下集效率会高很多。