热重载:救星也是坑

UE 的 Live Coding(热重载)允许不重启编辑器直接应用 C++ 改动,大幅缩短反馈循环——但它是个"半成品工具",需要清楚它的边界。

热重载的原理(决定了它的限制)

Live Coding 做的事情是:重新编译改动了的 .cpp,把新函数的机器码"贴"进进程。它没有重跑 UHT(Unreal Header Tool)、没有重建反射元数据、没有重新序列化资产。所以——凡是依赖"反射信息"和"已序列化数据"的东西,热重载都管不到。

这解释了下面所有"不能热重载"的条目:不是工具不努力,是它的工作机制根本够不着。

可以下的改动

  • 函数体的修改(逻辑、数值、算法);
  • 已有函数的参数(多数情况);
  • 新增成员变量(多数情况,但新加 UPROPERTY 的序列化要小心);
  • 修改非反射的普通 C++ 类(如纯算法工具类)。

不要用热重载的改动

改动类型 风险
新增 UCLASS / 新增反射宏 元数据不匹配,蓝图引用可能全坏
修改 UPROPERTY 的说明符(如改 BlueprintReadOnly → ReadWrite) 蓝图端旧引脚错乱
结构体/枚举内存布局变化(删字段、改类型) 已有序列化数据可能损坏
构造函数里加组件 编辑器已创建的实例不会补上
新增 C++ 模块 模块加载表在启动时构建,热重载管不到

经验法则:改动涉及"类的结构"(成员、宏、布局、模块)时,老老实实全量编译 + 重启编辑器;只改函数内部时,热重载安全。

检测热重载坏掉的方法

  • 蓝图里出现"找不到函数/属性"的红色断针;
  • 编辑器一场(内容浏览器排序错乱、Details 不刷新、图标变白);
  • 蓝图编译失败但代码明明没问题;
  • CDO 的属性值"看起来是旧的"(改了默认值不生效)。

修复:关编辑器 → 用 Visual Studio/Rider 全量 Rebuild → 重新打开。绝大多数"玄学问题"全量编译后消失。要是死活不对,删掉 Binaries 和 Intermediate 目录再编译——这是 UE 版的"重启大法 plus"。

一个建议的节奏

  • 日常小改(函数体):热重载,1 分钟内见效;
  • 半天/一天的集成分支:全量编译 + 重启;
  • 每次提交前:全量编译一遍,避免把"热重载能跑"的代码提交给同事——同事打开后是全新进程,热重载的旧状态会原形毕露。

一个真实事故

某项目在热重载状态下给结构体加了个字段,测试一切正常;提交后同事更新代码,所有存档损坏——因为热重载没重跑序列化,开发机上的"旧布局数据"和正式编译后的"新布局"不兼容。结构体布局 = 存档兼容性,这条线永远不要让热重载碰。

本章小结

  • 热重载原理是"贴函数机器码",管不到反射元数据与序列化数据。
  • 安全区:函数体修改;危险区:类结构、说明符、结构体布局、新模块。
  • 玄学问题先怀疑热重载状态:全量编译 + 重启;顽固问题清 Binaries/Intermediate。
  • 结构体布局直接关系存档兼容性,一次都不能图省事。