Unity 输出Debug.log Debug.ErrorLog文件保存到本地

用法:直接挂到第一个场景内的游戏对象上即可。代码如下

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public abstract class MonoSingletonManager : MonoBehaviour where T : MonoSingletonManager
{
    protected static T instance = null;

    public static T GetInstance()
    {
        if (instance == null)
        {
            instance = FindObjectOfType();
        }

        return instance;
    }

    protected virtual void OnDestroy()
    {
        instance = null;
    }
}
public enum LogLevel
{
    LOG = 0,
    WARNING = 1,
    ERROR = 2,   
}
public class DebugHelper : MonoSingletonManager
{
    public LogLevel SaveLogLevel;
    public bool IsSameFile;
    Queue m_vLogs;
    FileInfo m_logFileInfo;
    static bool m_isInited;
    string logFolder;
    string logFilename;
    string path;

    private Dictionary logTypeLevelDict = null;
    private void Awake()
    {
        if (m_isInited)
        {
            Debug.Log("existed logfile object,break");
            Destroy(gameObject);
            return;
        }
        Init();
    }
    private void OnDestroy() 
    {
        //Application.logMessageReceived -= OnLogMessage;
        Application.logMessageReceivedThreaded -= OnLogMessageThread;
    }
    void FixedUpdate()
    {
        if (m_isInited)
        {
            this.Refresh(Time.fixedDeltaTime);
        }       
    }

    public void Init()
    {
        if (m_isInited)
        {
            return;
        }
        DontDestroyOnLoad(gameObject);
        m_isInited = true;
        logTypeLevelDict = new Dictionary() {
                { LogType.Log, LogLevel.LOG },
                { LogType.Warning, LogLevel.WARNING },
                { LogType.Assert, LogLevel.ERROR },
                { LogType.Error, LogLevel.ERROR },
                { LogType.Exception, LogLevel.ERROR }};
        // 创建文件
        DateTime timeNow = DateTime.Now;
#if UNITY_EDITOR
        logFolder = Application.dataPath+"/..";
#else
        logFolder = Application.persistentDataPath;
#endif
        if (IsSameFile)
        {
            path = logFolder + "/Log.txt";
        }else
        {
            path = logFolder + "/Log" + timeNow.ToString("yyyyMMddHHmmss") + ".txt";
        }

        m_logFileInfo = new FileInfo(path);
        var sw = m_logFileInfo.CreateText();
        sw.WriteLine("[{0}] - {1}", Application.productName, timeNow.ToString("yyyy/MM/dd HH:mm:ss"));
        sw.Close();
        Debug.Log("日志文件已创建:" + path);

        // 注册回调
        m_vLogs = new Queue();
        //Application.logMessageReceived += OnLogMessage;
        Application.logMessageReceivedThreaded += OnLogMessageThread;
        Debug.Log("日志系统已启动");
    }


    public void Refresh(float dt)
    {
        if (m_vLogs.Count > 0)
        {
            try
            {
                var sw = m_logFileInfo.AppendText();
                var item = m_vLogs.Peek(); // 取队首元素但先不移除
                var timeStr = item.time.ToString("HH:mm:ss.ff");
                var logStr = string.Format("{0}-[{1}]{2}", timeStr, item.logType, item.messageString);
                //if (item.logType.Equals(LogType.Error))
                if(logTypeLevelDict[item.logType].Equals(LogLevel.ERROR))
                {
                    logStr = string.Format("{0}-[{1}]{2}==>{3}", timeStr, item.logType, item.messageString, item.stackTrace);
                }
                sw.WriteLine(logStr);
                sw.Close();
                m_vLogs.Dequeue(); // 成功执行了再移除队首元素
            }
            catch (IOException ex)
            {
                Debug.Log(ex.Message);
            }
        }
    }

    private void OnLogMessage(string condition, string stackTrace, LogType type)
    {
        if(logTypeLevelDict[type]>= SaveLogLevel)
        {
            m_vLogs.Enqueue(new LogItem()
            {
                messageString = condition,
                stackTrace = stackTrace,
                logType = type,
                time = DateTime.Now
            });
        }      
    }

    void OnLogMessageThread(string condition, string stackTrace, LogType type)
    {
        if (logTypeLevelDict[type] >= SaveLogLevel)
        {
            m_vLogs.Enqueue(new LogItem()
            {
                messageString = condition,
                stackTrace = stackTrace,
                logType = type,
                time = DateTime.Now
            });
        }        
    }
}

public struct LogItem
{
    /// 
    /// 日志内容
    /// 
    public string messageString;

    /// 
    /// 调用堆栈
    /// 
    public string stackTrace;

    /// 
    /// 日志类型
    /// 
    public LogType logType;

    /// 
    /// 记录时间
    /// 
    public DateTime time;
}

 

你可能感兴趣的:(unity3D,插件)