# 坑-UE5引擎 > UE5 引擎相关的坑:Actor/Component 生命周期、初始化时序、引擎 API 陷阱等。 > 条目按 ID 排列。新增条目时同步更新 [INDEX.md](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,**必须 override `EndPlay`**,在里头: - `GetWorld()->GetTimerManager().ClearTimer(MyTimerHandle);`(清所有相关句柄) - `if (MyWidget) MyWidget->RemoveFromParent();`(Widget 还有效则移除) - **状态**: ✅正式方案(项目所有 Character 持有 Component 的卫生写法,保持一致) - **关联**: `Source/.../CollectionHUDComponent.cpp` EndPlay