Unity项目中用StreamWriter文件实现日志管理、记录

1,195 阅读3分钟

1.了解Unity中的日志类

在Unity中常用的日志类为Debug类,常用的日志记录方法如下图: image.png

(1)Debug.Log()方法打印一个message消息到Unity控制台; (2)Debug.LogWarning()方法打印一个warning message警告消息到Unity控制台; (3)Debug.LogError()方法打印一个Error message错误消息到Unity控制台;

我们在脚本中输入以下代码:

Debug.Log("这是一个日志消息");
Debug.LogWarning("这是一个警告消息");
Debug.LogError("这是一个错误消息");

运行Unity看控制台输出信息,正常的日志信息是白色的感叹号,警告日志是黄色三角形中带一个感叹号,错误日志是红色六边形带一个感叹号。 image.png 那么我们想实现项目运行时用文件记录项目运行日志,用Unity的Debug类就无法直接实现,我们使用.NET Framework中的一个常用类StreamWriter,用于将文本写入到流中。它提供了一组用于写入字符、字符串和行的方法,可以将数据以文本形式写入到文件、内存流或网络流等各种流中。

2.实现流文件记录Unity运行日志

2.1日志等级

日志记录等级我这里分为信息日志、警告日志以及错误日志。

    /// <summary>
    /// 日志等级
    /// </summary>
    public enum LogLevel
    {
        /// <summary>
        /// 错误日志
        /// </summary>
        Error = 0,

        /// <summary>
        /// 警告日志
        /// </summary>
        Warning = 1,

        /// <summary>
        /// 信息日志
        /// </summary>
        Information=2,
    }

2.2具体实现

写一个日志管理类LogManager,使用单例模式,在Start()方法中初始化日志管理。

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            // 获取exe文件所在目录的路径
            string path = Path.GetDirectoryName(Application.dataPath) ?? Application.dataPath;

            // 创建日志文件
            string filePath = Path.Combine(path, "log.txt");
            m_Writer = new StreamWriter(filePath, true, Encoding.UTF8);
            OnEnable();
        }

这里的路径是windows平台下的exe文件所在的路径,我们也可以自定义路径,使用Application.persistentDataPath持久路径OnEnable()方法用于注册捕获全局异常事件。

        /// <summary>
        /// 注册全局异常捕获事件
        /// </summary>
        private void OnEnable()
        {
            Application.logMessageReceived += HandleLog;
        }

程序退出时执行以下方法OnDisable()用于取消注册捕获全局异常事件,同时关闭、释放和清理 StreamWriter 对象,并将 m_Writer 引用设置为 null,以便后续使用时进行必要的判断,可以避免资源泄漏和潜在的错误。

        /// <summary>
        /// 程序退出
        /// </summary>
        public void Quit()
        {
            OnDisable();
            if (m_Writer != null)
            {
                m_Writer.Close();
                m_Writer.Dispose();
                m_Writer = null;
            }
        }
        /// <summary>
        /// 取消注册全局异常捕获事件
        /// </summary>
        private void OnDisable()
        {
            Application.logMessageReceived -= HandleLog;
        }

捕获Unity全局异常事件句柄如下,这里我将警告信息也进行记录。

        /// <summary>
        /// 捕获全局异常事件
        /// </summary>
        /// <param name="logString">
        /// The log string.
        /// </param>
        /// <param name="stackTrace">
        /// The stack trace.
        /// </param>
        /// <param name="type">
        /// The type.
        /// </param>
        private void HandleLog(string logString, string stackTrace, LogType type)
        {
            if (type == LogType.Error || type == LogType.Exception)
            {
                // 捕获到错误或异常时,记录日志
                LogToFile(logString, LogLevel.Error);
                LogToFile(stackTrace, LogLevel.Error);
            }
            else if (type == LogType.Warning)
            {
                // 捕获到警告时,记录日志
                LogToFile(stackTrace, LogLevel.Warning);
            }
        }

日志写入文件

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="log">
        /// 日志信息
        /// </param>
        /// <param name="level">
        /// 日志等级
        /// </param>
        public void LogToFile(string log, LogLevel level)
        {
            var currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var logStr = "[" + level.ToString() + "] " + "[" + currentTime + "] " + log;

            // 将日志写入文件
            m_Writer.WriteLine(logStr);
        }

2.3日志记录

实现如下: image.png

3.结语

今天分享的只是其中一种实现方法,详细的代码已贴出,具体的使用可参考我的文章从0开始,用Unity写一个“健壮”的贪吃蛇游戏,难免有错误之处,欢迎大家批评指正!