1. 死亡逻辑重写从父类 OnDie 到玩家与机器人各自实现在 UE5 里做 FPS 游戏死亡处理看起来简单真写起来坑不少。我最近在重写项目里的死亡流程核心目标就三件事玩家和机器人死亡后能正确切换相机、替换或隐藏模型、并且整个流程不因为控制器提前分离而崩掉。这篇笔记聚焦的就是这套死亡逻辑的重写包括父类OnDie的定义、玩家子类的相机延后移动与模型替换、机器人子类的布娃娃与死亡动画两种方案以及死亡事件触发后的验证步骤。如果你正在做 UE5 FPS角色死亡后相机卡住、模型不消失、或者分离控制器后拿不到相机组件这篇应该能直接对上你的问题。下面所有节点配置和代码都可以照着复现我会把踩过的坑和排查方法一起写清楚。2. 前置准备TaoToken 接入与项目环境确认在开始改蓝图之前先把模型调用和项目环境理顺。我这边调试死亡逻辑时经常需要让 AI 帮忙看蓝图节点命名、查 UE5 的 API 签名所以会用到 TaoToken 的模型对话能力。它的接入方式很简单官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 这个地址不带 UTM 参数。如果你只是想让 AI 帮你解释某个蓝图节点的英文名直接用模型对话就行https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。要是你打算长期在 UE5 项目里做编码辅助比如批量改 C 或生成蓝图逻辑说明可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。需要自己管理密钥的话控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite API Keys 页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。项目环境这边确认你的 UE5 版本是 5.3 或以上FPS 模板已经能正常跑起来玩家角色和机器人角色都继承自同一个父类我这边叫AFPSCharacterBase。父类里已经有TakeDamage的重写机器人有独立的 AI 控制器玩家有第一人称相机组件。这些是后面改死亡逻辑的基础。3. 父类 OnDie 定义与公共死亡逻辑3.1 在父类中声明 OnDie父类里定义OnDie方法不需要实现交给子类各自处理死亡表现。C 里这样写// FPSCharacterBase.h UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category Death) void OnDie(); virtual void OnDie_Implementation();BlueprintNativeEvent的好处是 C 和蓝图都能重写子类蓝图里直接实现OnDie事件就行。父类里OnDie_Implementation可以留空或者只做最基础的标记比如设置bIsDead true。3.2 Die 方法处理公共逻辑再新建一个Die方法处理所有角色共用的死亡逻辑。关键点是以前的分离控制现在要延迟做。如果你在死亡瞬间就DetachFromControllerPendingDestroy那后面想拿玩家的相机组件、模型组件就全拿不到了因为控制器已经没了。// FPSCharacterBase.cpp void AFPSCharacterBase::Die() { if (bIsDead) return; bIsDead true; // 先处理死亡表现再分离控制器 OnDie(); // 延迟分离给子类留出获取组件的时间 FTimerHandle DetachTimer; GetWorldTimerManager().SetTimer( DetachTimer, this, AFPSCharacterBase::DetachController, 0.2f, false ); } void AFPSCharacterBase::DetachController() { DetachFromControllerPendingDestroy(); }这里用SetTimer延迟 0.2 秒分离而不是用Delay节点。蓝图里Delay节点在角色被销毁后可能不执行用 Timer 更稳。另外蓝图里延迟调用函数时函数名如果是中文节点上显示的是中文但底层还是英文名。你可以右键节点选「前往代码定义」看源码里的名字不过我这边打不开目前已知不是没装源码的问题具体原因还不清楚以后知道了补上。建议直接用英文名查节点比如Set Timer by Function Name。3.3 修改 TakeDamage 直接调用死亡父类的TakeDamage里血量扣到 0 以下就直接调Diefloat AFPSCharacterBase::TakeDamage(float DamageAmount, FDamageEvent const DamageEvent, AController* EventInstigator, AActor* DamageCauser) { float ActualDamage Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); Health - ActualDamage; if (Health 0.f) { Die(); } return ActualDamage; }这样玩家和机器人共用同一套伤害入口死亡触发统一走Die子类只需要重写OnDie做各自的表现。4. 玩家死亡相机延后移动与模型替换4.1 玩家 OnDie 重写玩家蓝图里重写OnDie事件。核心两步让相机延后移动 4 米然后更换模型。相机延后移动的意思是玩家死亡后视角不要立刻切走而是等一小段时间让相机从第一人称位置往后拉 4 米形成一个「死亡视角」的效果。蓝图里用Set Timer by Event配合Lerp或者Timeline来做。具体节点配置Event OnDie - Set Timer by Event (Time: 0.1, Looping: false) - 自定义事件 MoveCameraBack - Get Player Camera Manager - Set View Target with Blend (New View Target: 死亡相机Actor, Blend Time: 1.5)如果你不想新建相机 Actor也可以直接操作玩家相机的相对位置Event OnDie - Get Camera Component - Set Relative Location (Target: 相机, New Location: (0, -400, 0), Sweep: false)这里 400 单位约等于 4 米。注意要在分离控制器之前做否则Get Camera Component会返回空。4.2 更换模型模型替换有两种做法。一种是直接隐藏原模型生成一个死亡姿态的静态网格体另一种是切换骨骼网格体的动画蓝图播放死亡动画。隐藏原模型Event OnDie - Get Mesh (角色骨骼网格体) - Set Visibility (New Visibility: false, Propagate to Children: true)生成死亡模型Event OnDie - Spawn Actor from Class (Class: BP_DeathBody, Location: Get Actor Location, Rotation: Get Actor Rotation)BP_DeathBody里放一个带布娃娃或死亡姿态的骨骼网格体这样玩家死亡后原地留下一个尸体模型相机往后拉视觉上比较自然。4.3 死亡方式一使用死亡动画如果项目里有死亡动画资源直接在角色骨骼网格体上播放Event OnDie - Get Mesh - Play Animation (Anim to Play: Death_Anim, Looping: false)播放死亡动画的优点是可控缺点是动画播完后角色还是站立姿态的碰撞需要额外处理碰撞禁用。4.4 死亡方式二布娃娃死亡布娃娃更真实配置也简单。启用模拟物理并启用碰撞Event OnDie - Get Mesh - Set Simulate Physics (Simulate: true) - Set Collision Enabled (New Type: Collision Enabled (Query and Physics)) - Set Collision Profile Name (Profile Name: Ragdoll)也可以直接在蓝图里设置布娃娃选中骨骼网格体组件在 Details 面板里勾选Simulate Physics然后在 Collision 里修改碰撞预设为Ragdoll启用碰撞。这样角色死亡瞬间就会瘫软下去。注意布娃娃启用后角色的胶囊体碰撞还在可能会和布娃娃网格体打架。建议在OnDie里把胶囊体碰撞关掉Event OnDie - Get Capsule Component - Set Collision Enabled (New Type: No Collision)5. 机器人死亡AI 停止与模型处理机器人的死亡逻辑和玩家类似但多了 AI 控制器的处理。机器人死亡后先停止 AI 行为树再处理模型。Event OnDie (机器人蓝图) - Get Controller - Cast to AIController - Stop Movement - UnPossess (或者 Detach from Controller) - Get Mesh - Set Simulate Physics (true) - Set Collision Profile Name (Ragdoll)机器人不需要相机切换所以OnDie里不用管相机。但要注意如果机器人死亡后 AI 控制器还在跑行为树可能会继续尝试移动尸体。所以Stop Movement和UnPossess要放在前面。机器人模型处理也可以用死亡动画替代布娃娃看项目需求。我这边机器人用的是布娃娃因为 FPS 里机器人被击中后瘫倒比较有反馈感。6. 验证请求与成功结果改完死亡逻辑后按下面步骤验证第一步运行游戏用调试命令DamageTarget 999或者直接射击机器人观察机器人是否立刻进入布娃娃状态AI 是否停止移动。第二步让玩家死亡比如被机器人打死或者用控制台命令Kill。观察相机是否在 0.1 秒后开始往后拉 4 米模型是否隐藏或替换成尸体。第三步检查控制器分离时机。在DetachController里加一个Print String确认它在OnDie之后 0.2 秒才执行。如果提前执行了相机和模型组件会拿不到。第四步用ShowDebug命令查看角色状态确认bIsDead标记正确死亡后不会重复触发Die。成功的结果是玩家死亡后视角平滑后拉尸体模型留在原地机器人死亡后瘫倒且 AI 停止整个流程没有报错控制器在表现处理完之后才分离。7. 本篇常见错排查错误一分离控制器后拿不到相机组件。原因是在OnDie之前就调用了DetachFromControllerPendingDestroy。解决方法是把分离逻辑放到 Timer 里延迟执行确保OnDie先跑完。错误二蓝图里 Delay 节点不执行。角色死亡后如果被销毁Delay节点可能不触发。改用Set Timer by Event或Set Timer by Function Name稳定性更好。错误三布娃娃启用后角色抖动或飞出去。通常是胶囊体碰撞和布娃娃网格体碰撞重叠导致的。在OnDie里把胶囊体碰撞设为No Collision布娃娃碰撞预设设为Ragdoll。错误四机器人死亡后 AI 还在跑。检查OnDie里是否调用了Stop Movement和UnPossess。如果行为树里有Move To任务还需要在行为树里加一个死亡分支收到死亡事件后直接Finish Task。错误五相机移动方向不对。Set Relative Location的坐标是相对相机自身的如果你想要世界空间的后拉用Set World Location或者把相机挂到一个 Scene Component 上再移动父组件。排查的时候我习惯在关键节点后面加Print String输出当前是否拿到相机、是否拿到模型、控制器是否还在。这样能快速定位是哪一步断了。8. 接入与调试资源死亡逻辑重写完之后如果你想让 AI 帮你检查蓝图节点命名或者生成 C 的死亡流程代码可以用 TaoToken 的模型对话https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。需要自己管理密钥的话API Keys 页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。如果你打算长期在 UE5 项目里做编码辅助比如批量改 C 或生成蓝图逻辑说明可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentdeath_logicutm_campaignrewrite 。我实测下来死亡逻辑最容易出问题的地方就是控制器分离时机和布娃娃碰撞。把这两个点处理好玩家和机器人的死亡表现基本就稳了。