用途
该技能用于在 Unreal Engine C++ 项目中添加结构化日志与运行时检查,帮助开发者快速定位 UE 缺陷。核心原则是:使用日志类别而非 LogTemp,选择合适的详细级别以保持日志可读,并有意区分 check 与 ensure——前者中止程序,后者报告并继续。
主要能力
日志类别
每次 UE_LOG 调用都需指定类别。原型阶段可用内置 LogTemp,生产环境应为每个模块定义独立类别,以便在 Output Log 中过滤。声明方式为在头文件中使用 DECLARE_LOG_CATEGORY_EXTERN(LogMyFeature, Log, All),并在 .cpp 中通过 DEFINE_LOG_CATEGORY(LogMyFeature) 提供定义。文件私有类别可使用 DEFINE_LOG_CATEGORY_STATIC,无需头文件声明。编译期最大详细级别决定哪些级别被编译进代码,设为 Warning 会在编译期剥离 Log/Verbose/VeryVerbose 调用。
UE_LOG 格式化日志
基本用法为 UE_LOG(类别, 详细级别, TEXT("格式"), 参数...)。格式说明符中 %s 期望 const TCHAR*,需用 * 解引用 FString;%d 为 int32,%f 为 float/double,%p 为指针。UE_CLOG 为条件变体,仅当条件为真时才求值格式。
UE_LOGFMT 结构化日志(UE 5.2+)
UE_LOGFMT 记录带命名字段的结构化日志事件,支持机器可读输出。需包含 "Logging/StructuredLog.h"。支持位置式与命名式两种字段映射,字段名须匹配 [A-Za-z0-9_]+ 且在调用内唯一,不可混用两种风格。单次调用最多支持 16 个字段,更多字段可用 UE_LOGFMT_EX 配合 UE_LOGFMT_FIELD 包装。
详细级别
从最严重到最轻:Fatal(立即崩溃,即使 NO_LOGGING 也始终运行)、Error(控制台与日志文件,红色高亮)、Warning(控制台与日志文件,黄色高亮)、Display(控制台与日志文件,不频繁的信息事件)、Log(仅日志文件,常规操作信息)、Verbose(类别启用时写入日志文件,默认禁用)、VeryVerbose(每帧或高频跟踪)。运行时可通过控制台命令 Log LogMyFeature Verbose 或命令行 -LogCmds="LogMyFeature Verbose" 调整,但运行时级别不能超过编译期最大值。
断言
三类断言宏:check/checkf/checkSlow/checkNoEntry 在开发版中止并输出调用栈,发行版被编译掉,表达式不运行;verify/verifyf 在开发版失败时中止,发行版表达式仍运行但不中止;ensure/ensureMsgf/ensureAlways 记录日志并继续,发行版表达式运行但不报告。游戏代码建议优先使用 ensure 而非 check,以便在编辑器中继续运行并调查坏状态;check 仅用于真正不变的条件。
屏幕调试消息(仅 PIE)
通过 GEngine->AddOnScreenDebugMessage 显示,键 -1 表示不去重,稳定非负整数可覆盖同一行。需用 #if !UE_BUILD_SHIPPING 门控或发布前移除。
日志输出位置
编辑器 Output Log(Window › Output Log,按类别名过滤)、磁盘日志文件 <Project>/Saved/Logs/<ProjectName>.log、游戏内控制台(~ 键,Log CategoryName Verbosity 调整级别)。
使用方式
为新模块或功能子系统定义日志类别;为上下文添加合适详细级别的 UE_LOG / UE_LOGFMT 调用;在 check、verify、ensure 之间为给定假设做选择;决定坏状态应崩溃还是仅报告;在运行时或构建中按类别过滤或静默详细日志。
适用场景
需要为新游戏模块或功能子系统定义日志类别时;需要为上下文选择正确详细级别时;需要在 check、verify、ensure 之间做选择时;需要决定坏状态是否应崩溃时;需要按类别过滤或静默日志时。
限制与注意事项
%s 直接传 FString 而不加 * 会读取垃圾字节,是最常见的日志错误。check 在发行版被编译为空,切勿在 check(expr) 中放置必需的副作用,若调用必须执行应使用 verify(expr)。ensure 默认每个调用点在单次会话中仅触发一次,第二次命中会被静默跳过,若每次出现都重要应使用 ensureAlways。在 tick 中以 Log 或 Warning 级别记录会刷屏并拖慢编辑器,应使用 Verbose/VeryVerbose 或 UE_CLOG 条件化。编译期详细级别过低会静默剥离更详细级别的调用。Fatal 详细级别始终运行,即使定义了 NO_LOGGING。UE_LOGFMT 需要包含 "Logging/StructuredLog.h",缺失会产生未定义宏错误。
版本说明
UE_LOGFMT 与 UE_LOG_CONTEXT 于 UE 5.2 引入,稳定至 5.8。FStaticEnsureRecord 每调用点机制(原子 bGEnsureHasExecuted)在 UE 5.x 中取代了更简单的布尔值,用户可见的宏签名未变。LowLevelFatalErrorHandler 在 5.7 中弃用,应使用 LowLevelFatalError 宏。