在使用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;
}