3、日志系统入门:Debug.Log、打印技巧、日志分级、日志文件管理

日志系统,说白了就是游戏运行时的「黑匣子」。

你想想看,游戏跑起来之后,我们看不到内部状态。变量对不对?逻辑走没走?报错在哪?全靠日志告诉我们。我个人习惯,写代码之前先把日志想好——这不是小题大做,是血的教训换来的。

3.1 Debug.Log:最基础的打印

Unity 里最常用的就是 Debug.Log()。用法很简单:

Debug.Log("玩家进入关卡");
Debug.Log("当前血量:" + hp);
Debug.Log($"坐标:{transform.position}");  // C# 字符串插值

嗯,这里要注意:字符串拼接在频繁调用时会有性能开销。我在项目中遇到过,某个战斗系统每帧打印几十条日志,结果手机发烫严重。后来全改成条件编译才解决。

小技巧:Debug.LogFormat() 或字符串插值,比用 + 拼接更优雅,性能也稍好。

3.2 打印技巧:别只会用 Log

Unity 其实给了我们三种打印方法:

方法 用途 编辑器颜色
Debug.Log() 普通信息 白色
Debug.Warning() 警告信息 黄色
Debug.Error() 错误信息 红色

为什么要区分?因为扫日志的时候,黄色和红色能让你一眼定位问题。我曾经接手过一个项目,全用 Debug.Log(),几万行日志混在一起,找错误像大海捞针。

还有一个实用技巧:打印对象引用

Debug.Log("敌人死亡", enemyObj);

这样在 Console 窗口点击日志,会自动高亮对应的游戏对象。调试时特别方便,省得你满场景找物体。

核心原则:日志要让人「一眼看懂」——谁、在哪、发生了什么。

3.3 日志分级:别让日志刷屏

游戏开发中,日志量是惊人的。如果不分级,你会发现 Console 窗口刷得飞起,真正有用的信息反而被淹没了。

我一般把日志分成四个级别:

  • Error(错误):游戏崩溃、资源加载失败、关键逻辑异常。必须修复。
  • Warning(警告):可能有问题但不致命,比如配置缺失、性能警告。
  • Info(信息):正常流程记录,比如玩家进入场景、任务完成。
  • Debug(调试):开发阶段用的细粒度日志,发布时应该关掉。

怎么实现分级?我习惯写一个简单的日志管理器:

public enum LogLevel
{
    Debug,
    Info,
    Warning,
    Error
}

public static class Logger
{
    public static LogLevel CurrentLevel = LogLevel.Debug;

    public static void Log(LogLevel level, string message)
    {
        if (level < CurrentLevel) return;

        switch (level)
        {
            case LogLevel.Debug:
                Debug.Log("[DEBUG] " + message);
                break;
            case LogLevel.Info:
                Debug.Log("[INFO] " + message);
                break;
            case LogLevel.Warning:
                Debug.LogWarning("[WARN] " + message);
                break;
            case LogLevel.Error:
                Debug.LogError("[ERROR] " + message);
                break;
        }
    }
}

使用时:

Logger.Log(LogLevel.Info, "玩家进入关卡");
Logger.Log(LogLevel.Debug, "怪物AI状态切换");  // 发布时关掉
注意:发布版本一定要把 Debug 级别的日志关掉。我曾经有个项目,Debug 日志里不小心打印了完整的玩家数据,结果被玩家抓包反编译……嗯,很尴尬。

3.4 日志文件管理:让日志「可追溯」

编辑器里看日志很方便,但游戏发布到玩家手机上怎么办?这时候就需要日志文件了。

我常用的方案:

  • 写入本地文件:用 Application.persistentDataPath 作为路径
  • 按日期分文件:每天一个日志文件,方便查找
  • 限制文件大小:超过 10MB 自动滚动,防止撑爆存储

一个简单的文件日志实现:

using System.IO;
using System.Text;

public class FileLogger
{
    private static string logPath;
    private static StringBuilder sb = new StringBuilder();

    public static void Init()
    {
        logPath = Application.persistentDataPath + "/logs/";
        if (!Directory.Exists(logPath))
            Directory.CreateDirectory(logPath);
    }

    public static void Write(string message)
    {
        string fileName = "log_" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
        string fullPath = logPath + fileName;

        sb.Clear();
        sb.Append("[");
        sb.Append(DateTime.Now.ToString("HH:mm:ss"));
        sb.Append("] ");
        sb.AppendLine(message);

        File.AppendAllText(fullPath, sb.ToString());
    }
}

调用时:

FileLogger.Write("玩家登录,ID: 10086");
进阶建议:加上「日志上传」功能。玩家遇到 bug 时,一键上传日志文件到服务器,能极大提升排查效率。我在项目中就靠这个功能,远程定位了好几个诡异的闪退问题。

3.5 避坑指南

最后分享几个我踩过的坑:

  • 不要在 Update 里打日志——每帧打印,手机瞬间变暖手宝
  • 日志里不要放敏感信息——玩家账号、设备 ID 等,容易被抓包
  • 日志文件记得加密或混淆——防止玩家恶意篡改
  • 发布前检查所有 Debug.Log——我习惯用宏控制,发布版本自动移除

日志系统看似简单,但用好了能省下大量调试时间。记住一句话:好的日志,是写给未来自己的信