b2820ec024
- 新增 problem-solving skill:固化「问题分析→工作记录→知识沉淀」9步流程与3模板 - 新建 docs/knowledge/ 经验知识库(README/INDEX/临时方案登记/坑-UE5引擎含2条迁移示例) - GIT-GUIDE 补 §2.7 临时代码 [TEMP-INVESTIGATE] 约定、§2.8 fix 提交引用 issue - CLAUDE.md 项目管理段加问题管理引用 - 配套 Gitea 标签 type:bug / type:investigation(后台已建)
2.3 KiB
2.3 KiB
坑-UE5引擎
UE5 引擎相关的坑:Actor/Component 生命周期、初始化时序、引擎 API 陷阱等。 条目按 ID 排列。新增条目时同步更新 INDEX.md。
[K-001] Actor BeginPlay 时序竞争:子系统 Driver 可能晚于 Character 初始化
- 来源: P-013 实现偏差报告 · 偏差3
- 症状: 在
AChildHoodCharacter::BeginPlay中通过ASystemDriver::Get取 Driver,再读子系统(如收集系统)的进度数据时,可能读到未初始化的值(Progress=0、CollectedIDs 空),导致进度 Widget 显示错误或存档恢复失败。 - 根因: UE5 不保证不同 Actor 的 BeginPlay 执行顺序。Character 可能先于
ASystemDriver完成 BeginPlay——此时 Driver 虽然存在,但其持有的子系统尚未执行RestoreFromPersistence。 - 避坑做法: 不要在
BeginPlay/Initialize里立即创建依赖其他子系统的对象、或读取其状态。改为首次有效 Tick 时懒创建——等到 World 完全就绪、依赖子系统完成初始化后再创建/读取。 - 状态: ✅正式方案(已用于
UCollectionHUDComponent的进度 Widget 创建) - 关联:
docs/technical/收集系统-技术方案.md§6、Source/.../CollectionHUDComponent.cpp
[K-002] Component 持有的 Timer / Widget 必须在 EndPlay 清理,防 Respawn 野指针
- 来源: P-013 实现偏差报告 · 审查修复2
- 症状: 角色 Respawn(销毁旧 Character、重建新 Character)时崩溃——旧 Component 上还挂着
SetTimer注册的回调,触发时访问已销毁的 UMG Widget,野指针。 - 根因: Component 被销毁时,UE 不会自动清理你手动注册的
FTimerHandle,也不会自动移除AddToViewport的 Widget。这些引用悬挂,下次 Tick 或 Timer 触发即崩。 - 避坑做法: 凡是 Component 持有
FTimerHandle(SetTimer注册过)或AddToViewport的 UMG Widget,必须 overrideEndPlay,在里头:GetWorld()->GetTimerManager().ClearTimer(MyTimerHandle);(清所有相关句柄)if (MyWidget) MyWidget->RemoveFromParent();(Widget 还有效则移除)
- 状态: ✅正式方案(项目所有 Character 持有 Component 的卫生写法,保持一致)
- 关联:
Source/.../CollectionHUDComponent.cppEndPlay