日志工具

LogUtil 为框架提供统一的日志输出工具,支持 模块自动识别、彩色标签、分类日志级别、逻辑环境开关(DebugMode) 等能力。 相比直接使用 Unity 的 Debug.Log,LogUtil 提供更一致、更规范的调试体验,并支持自动定位调用者模块名。

LogUtil 的主要设计目标:

  • 为每条日志自动生成模块标签(根据调用类自动识别)
  • 支持 Info、Success、Warn、Error 四种日志类型
  • 支持 DebugMode 控制是否输出(发布版可自动屏蔽日志)
  • 统一输出格式,便于快速定位模块问题
  • 线程安全的调用方缓存(提升性能)

1. 日志输出等级

LogUtil 提供四类日志:

  • Info:一般信息
  • Success:成功提示(✓)
  • Warn:警告提醒(!)
  • Error:错误日志(✗)

所有日志自动带有模块标签 [ModuleName],模块名为调用该方法的类名。


2. 基本用法

2.1 输出信息日志(Info)

自动识别模块名:

LogUtil.Info("加载完成");

指定模块名:

LogUtil.Info("DataLoader", "读取配置成功");

强制输出:

LogUtil.Info("重要日志", force: true);

3. 成功日志(Success)

LogUtil.Success("生成数据文件成功");

带模块:

LogUtil.Success("ExcelTool", "表格解析完成");

4. 警告日志(Warn)

LogUtil.Warn("配置字段缺失,将按默认值处理");
LogUtil.Warn("Parser", "字段名为空,将跳过解析");

5. 错误日志(Error)

LogUtil.Error("读取数据失败:文件不存在");
LogUtil.Error("ExcelTool", "解析失败,数据格式错误");

错误日志永远输出。


6. 模块标签自动识别

几乎所有情况下,LogUtil 都能通过 StackTrace 自动识别调用者类名,例如:

public class DataLoader
{
    void Load()
    {
        LogUtil.Info("开始加载");
    }
}

输出:

[DataLoader] 开始加载

6.1 调用者类名解析的限制说明

Fink Framework 的 LogUtil 采用增强型调用栈解析,并支持匿名类外层类名恢复,能在 绝大多数游戏逻辑代码 中正确显示调用代码所在类的名字。

例如:

  • 普通方法
  • 匿名函数 / lambda
  • 闭包(DisplayClass)
  • 协程(包括 yield 后执行)
  • TimerManager / UnityAction 回调

以上情况均可 百分百 获取调用者真实类名。

但以下情况受 Unity / C# / IL2CPP 限制,无法保证解析到真实调用类:

  • 通过 Reflection(MethodInfo.Invoke) 调用的代码
  • Unity 内部调用(如 UnityEvent Inspector 绑定方法)
  • IL2CPP Release 模式(部分栈帧会被优化掉)
  • async/await 生成的状态机类(类名不一定可逆解析)
  • 某些 AOT 生成的 wrapper 函数
  • 来自 Unity 引擎系统层的回调

这些情况调用栈可能不包含用户代码的实际类名,因此 LogUtil 无法恢复精确调用者。
所以为了更稳妥的显示调用者建议显式传入模块名打印(即使获取不到也不会影响任何代码逻辑)。


7. DebugMode 控制(全局开关)

  • DebugMode = true:全部日志输出
  • DebugMode = false:只输出 Error 和 force=true 的日志

示例:

LogUtil.Info("必须输出", force: true);

日志工具总结

LogUtil 提供:

  • 模块自动识别
  • 四类日志:Info / Success / Warn / Error
  • DebugMode 环境控制
  • 可强制输出
  • 统一格式和彩色显示
  • 多线程安全缓存机制

它是框架调试、安全检查、数据工具、运行时模块中最常用的日志工具。