目录
Unity 工具类 之 日志本地化保存和简单界面显示日志
一、简单介绍
二、实现原理
三、注意事项
四、实现步骤
五、关键代码
六、参考资料
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
本节介绍,在Unity中如何简单显示日志并且保存日志到本地的功能。
1、定义一个日志保存路径,以一天为单位记录日志,写入文件
2、OnGUI 显示简单的调试日志(待完善)
3、Application.logMessageReceived 添加日志调用事件,实现日志保存
1、注意安卓移动端手动关闭后台应用是 调用不到 Unity 的 OnDestroy() 和 OnApplicationQuit() 函数
2、日志有缓冲队列,可以自行设置缓冲数量
3、window 上 日志保存在 Application.persistentDataPath 路径下,而移动端,可以保存等到你设置的路径,也可以默认在
Application.persistentDataPath 路径下
1、打开Unity,新建一个工程
2、在工程中添加三个脚本,DebugWrapper,重新封装 Debug,而且扩展了时间函数;LoggerManager 添加事件保存日志,和显示日志;Test 脚本添加测试日志本地保存情况
3、在场景中添加一个游戏物体,挂载LoggerManager脚本上去,并且设置保存日志的标签,和保存路径
4、在场景中添加一个游戏物体,挂载 Test 脚本上去
5、运行结果
6、指定路径下有保存的日志文件
1、ManagerLoger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 日志的保存
/// 包括保存所有日志还是日志标签的日志
/// 保存地址,可以默认保存地址,也可以指定保存的地址(电脑上是默认)
/// 若果不需要显示 OnGUI()可以注释掉哈
///
public class LoggerManager : MonoBehaviour
{
[Tooltip(" TAG 为空记录所有日志,TAG 不为空,只记录 TAG 的日志")]
[Header("记录日志标签")]
public string TAG;
[Tooltip(" saveLogPath 为空日志保存地址为Application.persistentDataPath + ‘/ PlusLogs / ’ + System.DateTime.Now.TimeDay() + ‘_Log.txt’,saveLogPath 不为空,日志保存路径为指定路径")]
[Header("日志保存地址")]
public string saveLogPath;
private System.IO.FileInfo fileLogPath;
private bool isDebug = true;
private Queue queueLogs;
private int maxCount = 1;
private bool isShowDetail = false;
void Awake()
{
Init();
}
///
/// 初始化
///
void Init() {
// 是否指定日志保存的位置,没有即默认一个位置
if (string.IsNullOrEmpty(saveLogPath) || Application.platform == RuntimePlatform.WindowsEditor)
{
fileLogPath = new System.IO.FileInfo(Application.persistentDataPath + "/LogSaveFiles/" + Application.identifier +
"-"+Application.productName+"-"+Application.version +"-"+ System.DateTime.Now.TimeDay() + "_Log.txt");
}
else
{
fileLogPath = new System.IO.FileInfo(saveLogPath);
}
// 日志队列初始化
queueLogs = new Queue();
// 查看是否有指定的路径日志文件
if (!fileLogPath.Exists)
{
if (!System.IO.Directory.Exists(fileLogPath.DirectoryName))
{
System.IO.Directory.CreateDirectory(fileLogPath.DirectoryName);
}
fileLogPath.Create();
}
//Application.RegisterLogCallback(HandleLog);老版本这么写的
Application.logMessageReceived += HandleLog;
if (isDebug)
{
DebugWrapper.Log("初始化日志文件成功,日志保存路径为 : " + fileLogPath.FullName);
}
}
///
/// 系统处理日志的事件函数
///
///
///
///
void HandleLog(string logString, string stackTrace, LogType type)
{
// 是否过滤只保存需要的日志(TAG 为要保存的日志标签)
if (string.IsNullOrEmpty(TAG) == false)
{
if (logString.Contains(TAG) == false)
{
return;
}
}
// 处理日志字符串
string[] s = stackTrace.Split('\n');
stackTrace = string.Empty;
foreach (string line in s)
{
stackTrace += " " + line + '\n';
}
// 把日志添加到队列中
lock (queueLogs)
{
queueLogs.Enqueue(string.Format("{0} : {1}\r\n{2} {3}", type, logString, stackTrace, "\n"));
// 日志队列满足数量,及保存日志
if (queueLogs.Count >= maxCount)
{
WriteLocal();
}
}
}
///
/// 写入日志文件
///
void WriteLocal()
{
try
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileLogPath.FullName, true))
{
while (queueLogs.Count > 0)
{
file.Write(queueLogs.Dequeue());//直接追加文件末尾
}
}
}
catch (System.Exception e)
{
throw (e);
}
}
///
/// 读取日志文件
///
///
public string ReadLogFile()
{
try
{
return System.IO.File.ReadAllText(fileLogPath.FullName);
}
catch (System.Exception e)
{
return "日志文件读取错误:" + e.Message;
}
}
private Vector2 scrollViewVector = Vector2.zero;
///
/// 绘制在界面上查看日志信息
///
void OnGUI()
{
// 调试的时候显示窗口
if (isDebug)
{
// 显示或关闭日志显示
if (isShowDetail)
{
if (GUI.Button(new Rect(Screen.width - 80, 50, 80, 50), "关闭日志"))
{
isShowDetail = false;
}
GUI.TextArea(new Rect(0, 100, Screen.width, Screen.height - 100), ReadLogFile());
}
else
{
if (GUI.Button(new Rect(Screen.width - 80, Screen.height - 50, 80, 50), "显示日志"))
{
isShowDetail = true;
}
}
}
}
///
/// 在销毁的时候,把未保存的保存下(任选一个)
///
void OnDestroy()
{
//Debug.Log("XAB OnDestroy WriteLocal()");
//WriteLocal();
}
///
/// 在退出应用的时候,把未保存的保存下(任选一个)
///
void OnApplicationQuit()
{
//Debug.Log("XAB OnApplicationQuit WriteLocal()");
WriteLocal();
}
}
2、DebugPlus.cs
using UnityEngine;
///
/// 重新简单封装Unity日志
/// 添加上时间信息
///
public static class DebugWrapper
{
public static void Log(string info)
{
Debug.Log(System.DateTime.Now.TimeFormat() + " : " + info);
}
public static void LogError(string info)
{
Debug.LogError(System.DateTime.Now.TimeFormat() + " : " + info);
}
public static void LogWarning(string info)
{
Debug.LogWarning(System.DateTime.Now.TimeFormat() + " : " + info);
}
///
/// 扩展时间 now
///
///
///
public static string TimeFormat(this System.DateTime now)
{
return now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
}
///
/// 扩展时间 now
///
///
///
public static string TimeDay(this System.DateTime now)
{
return now.ToString("yyyy-MM-dd");
}
}
3、Test.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
private int i = 0;
private string TAG = "XAB";
// Use this for initialization
void Start()
{
//测试系统自带的日志和自己封装的日志(特别是在移动端,你发现不同,为什么封装啦哈)
Debug.Log("测试 看看");
Debug.Log(TAG+" Debug Debug.Log");
DebugWrapper.Log(TAG+" DebugWrapper.Log");
DebugWrapper.LogError(TAG+" DebugWrapper.LogError");
DebugWrapper.LogWarning(TAG+" DebugWrapper.LogWarning");
}
///
/// 测试手动插入数据
///
private void OnGUI()
{
if (GUI.Button(new Rect(0, 0, 100, 100), "写入日志测试"))
{
DebugWrapper.Log("插入日志" + i);
i++;
}
}
}
参考:https://blog.csdn.net/nicepainkiller/article/details/84958804
SRDebugger 工具可以参考使用,功能更加完善,建议使用哈