Unity應用發佈如何在本地查看Debug輸出?

在使用Unity引擎開發遊戲的過程中,我們能將想要看到的內容通過Debug類來輸出到Console窗口中,極大的方便了程序的調試過程。但是,我們將遊戲發佈成對應的平臺應用程序後,這些輸出還能不能看到呢?如可才能看到這些輸出呢?這裏我就介紹一種能夠將Unity引擎的Debug類的輸出寫入到本地硬件的方法。

委屈這裏只介紹Windows平臺與Android平臺。


Windows平臺:

默認情況下,打包應用到Windows平臺,運行程序後,我們能夠在“xxoo_Data”文件夾下看到“output_log.txt”文件,這個文件就是用來記錄我們代碼中調用的Debug類的輸出。

其他情況,其實““output_log.txt”文件是可以通過Unity引擎設置屏蔽的。Unity設置項中的“ Use Player Log”項就是控制是否將Debug類的輸出寫入到本地硬件(PC硬盤)的開關,默認選中。

設置方法“Editor -> Project Settings -> Player ->  選擇平臺(Windows) -> Resolution and Presentation -> Use Player Log”。當然,爲了提高程序的運行效率,在發佈程序正式版時,建議關閉這個開關。


Android平臺:

默認情況下,打包應用到Android後我們就看不到輸出了。怎樣才能在本地設備看到輸出呢?

首先,設置發佈配置“Editor -> Project Settings -> Player ->  選擇平臺(Android) -> Other Settings -> Write Access”。將“Write Access”設置成“External(SDCard)”。爲了提高程序運行效率,發佈到正式版時,最好不要選擇此項。

接下來我就不贅述了,直接看代碼:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;

/// <summary>
/// Debug測試。
/// 將Debug寫入到本地硬件
/// 這裏使用的是Unity5.3.3版本
/// </summary>
public class LoggerMono : MonoBehaviour
{
    public Text logText;
    public string logName = "123";
    private string m_txt;
    private float m_timeNote;
    private float m_timeNote2;
    public float m_duration = 2f;

    void Awake()
    {
        Application.logMessageReceived += OnLogCallBack;
        m_timeNote = Time.time;

        /// 這裏纔是重點,要將Debug輸出寫入到本地文件的關鍵。
        LoggerWriter.instance.InitWriter(logName);
    }

    private void OnLogCallBack(string condition, string stackTrace, LogType type)
    {
        string logStr = string.Empty;
        switch (type)
        {
            case LogType.Log:
                {
                    logStr = string.Format("{0}:{1}\n", type, condition);
                }
                break;
            case LogType.Assert:
            case LogType.Warning:
            case LogType.Exception:
            case LogType.Error:
                {
                    if (string.IsNullOrEmpty(stackTrace))
                    {
                        /// 發佈到對應平臺後,調用堆棧獲取不到。使用 Environment.StackTrace 獲取調用堆棧
                        logStr = string.Format("{0}:{1}\n{2}", type, condition, Environment.StackTrace);
                    }
                    else
                    {
                        logStr = string.Format("{0}:{1}\n{2}", type, condition, stackTrace);
                    }
                }
                break;
        }
        logStr += "\n";
        m_txt += logStr;
    }

    void Update()
    {
        if (logText != null)
        {
            logText.text = m_txt;
        }

        if (Time.time - m_timeNote >= m_duration)
        {
            m_timeNote = Time.time;
            Debug.Log(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
        }

        if (Time.time - m_timeNote2 >= 2.1f * m_duration)
        {
            m_timeNote2 = Time.time;
            Debug.LogError(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
        }
    }
}
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.IO.Compression;

/// <summary>
/// Debug輸出寫入本地硬件方法
/// </summary>
public class LoggerWriter
{
    /// <summary>
    /// 初始化文件寫入的入口
    /// </summary>
    /// <param name="logName"></param>
    public void InitWriter(string logName)
    {
        GetLogPath(logName);
        CreateLogFile();
    }

    /// <summary>
    /// 設置及獲取對應發佈平臺的日記存放路徑
    /// </summary>
    /// <param name="logName"></param>
    private void GetLogPath(string logName)
    {
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
                {
                    //m_logPath = "mnt/sdcard/123.txt";
                    //m_logPath = string.Format("{0}/123.txt", Application.persistentDataPath);
                    m_logPath = string.Format("mnt/sdcard/{0}.txt", logName);
                }
                break;
            case RuntimePlatform.IPhonePlayer:
                {
                    m_logPath = string.Format("{0}/{1}.txt", Application.persistentDataPath, logName);
                }
                break;
            case RuntimePlatform.WindowsPlayer:
                {
                    m_logPath = string.Format("{0}/../{1}.txt", Application.dataPath, logName);
                }
                break;
            case RuntimePlatform.WindowsEditor:
                {
                    //m_logPath = string.Format("{0}/123.txt", Application.dataPath);
                    m_logPath = string.Format("{0}/../{1}.txt", Application.dataPath, logName);
                }
                break;
            case RuntimePlatform.OSXEditor:
                {

                }
                break;
        }
    }

    /// <summary>
    /// 根據路徑創建日記文件,並註冊文件寫入的函數。
    /// </summary>
    private void CreateLogFile()
    {
        if (File.Exists(m_logPath))
        {
            File.Delete(m_logPath);
        }

        try
        {
            FileStream fs = File.Create(m_logPath);
            fs.Close();

            if (File.Exists(m_logPath))
            {
                Debug.Log(string.Format("Create file = {0}", m_logPath));
            }

            /// 註冊事件,當Debug調用時,就會調用:
            Application.logMessageReceived += OnLogCallBack;

            OutputSystemInfo();
        }
        catch (System.Exception ex)
        {
            Debug.LogError(string.Format("can't Create file = {0},\n{1}", m_logPath, ex));
        }
    }

    /// <summary>
    /// 日記文件寫入的函數
    /// </summary>
    /// <param name="condition"></param>
    /// <param name="stackTrace"></param>
    /// <param name="type"></param>
    private void OnLogCallBack(string condition, string stackTrace, LogType type)
    {
        if (File.Exists(m_logPath))
        {
            var filestream = File.Open(m_logPath, FileMode.Append);
            using (StreamWriter sw = new StreamWriter(filestream))
            //using (StreamWriter sw = File.AppendText(m_logPath))
            {
                string logStr = string.Empty;
                switch (type)
                {
                    case LogType.Log:
                        {
                            logStr = string.Format("{0}:{1}\n", type, condition);
                        }
                        break;
                    case LogType.Assert:
                    case LogType.Warning:
                    case LogType.Exception:
                    case LogType.Error:
                        {
                            if (string.IsNullOrEmpty(stackTrace))
                            {
                                /// 發佈到對應平臺後,調用堆棧獲取不到。使用 Environment.StackTrace 獲取調用堆棧
                                logStr = string.Format("{0}:{1}\n{2}\n", type, condition, Environment.StackTrace);
                            }
                            else
                            {
                                logStr = string.Format("{0}:{1}\n{2}", type, condition, stackTrace);
                            }
                        }
                        break;
                }

                sw.WriteLine(logStr);

            }
            filestream.Close();
        }
        else
        {
            Debug.LogError(string.Format("not Exists File = {0} !", m_logPath));
        }
    }

    /// <summary>
    /// 輸出系統/硬件等一些信息
    /// </summary>
    private void OutputSystemInfo()
    {
        string str2 = string.Format("logger Start, time: {0}, version: {1}.", DateTime.Now.ToString(), Application.unityVersion);

        string systemInfo = SystemInfo.operatingSystem + " "
                            + SystemInfo.processorType + " " + SystemInfo.processorCount + " "
                            + "memorySize:" + SystemInfo.systemMemorySize + " "
                            + "Graphics: " + SystemInfo.graphicsDeviceName + " vendor: " + SystemInfo.graphicsDeviceVendor
                            + " memorySize: " + SystemInfo.graphicsMemorySize + " " + SystemInfo.graphicsDeviceVersion;

        Debug.Log(string.Format("{0}\n{1}", str2, systemInfo));
    }

    public static LoggerWriter instance
    {
        get
        {
            if (s_instance == null)
            {
                s_instance = new LoggerWriter();
            }
            return s_instance;
        }
    }

    public string logPath
    {
        get { return m_logPath; }
    }

    private static LoggerWriter s_instance;
    private string m_logPath;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章