Unity输出Log开发日记到本地文件,Unity Log 本地化管理

环境:unity5.3,C#

目的:将信息写入到本地文件,方便查看。

方法一:

/*******************************************************************
Copyright © framework
Description: 日志输出
android日志放在Android/data/com.xxx.yyy/files/目录下
ios无法生成日记
Date: 2021-2-4
********************************************************************/

using System.IO;
using UnityEngine;
using System.Text;

public class Logger
{
    public void InitLogger()
    {
        string fileName = "outputlog.txt";
#if UNITY_EDITOR
        System.IO.DirectoryInfo dir = new DirectoryInfo(Application.dataPath);
        var fullSavePath = string.Format("{0}/{1}", dir.Parent.FullName, fileName);
        InitLogger(fullSavePath);
#elif UNITY_ANDROID
        //var fullSavePath = "mnt/sdcard/outputlog.txt";
        var fullSavePath = string.Format("{0}/Log/{1}", Application.persistentDataPath, fileName);
        InitLogger(fullSavePath);
#elif UNITY_IPHONE
        var fullSavePath = string.Format("{0}/{1}", Application.persistentDataPath, fileName);
        InitLogger(fullSavePath);
#elif UNITY_STANDALONE_WIN
        var fullSavePath = string.Format("{0}/{1}", Application.dataPath, fileName);
        InitLogger(fullSavePath);
#endif
    }

    void InitLogger(string fullSaveFile)
    {
        m_fullSaveFile = fullSaveFile;

        FileInfo fileInfo = new FileInfo(m_fullSaveFile);
        string path = fileInfo.DirectoryName;
        Debug.LogError(string.Format("---- path = {0}", path));

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        try
        {
            // 创建一个新文件,向其中写入指定的字符串,然后关闭文件。 如果目标文件已存在,则覆盖该文件。
            System.IO.File.WriteAllText(m_fullSaveFile, string.Empty, Encoding.UTF8);
            Debug.Log("Logger Start : " + path);
        }
        catch (System.Exception ex)
        {
            Debug.Log("error can not open." + ex.StackTrace.ToString() + ex.Message);
        }
    }

    private void logCallBack(string condition, string stackTrace, LogType type)
    {
        lock (s_locker)
        {
            if ((type == LogType.Error || type == LogType.Exception))
            {
                m_needUpload = true;
            }

            string strTime = System.DateTime.Now.ToString("MM-dd HH:mm:ss");
            string log = string.Format("{0} curframe:{1} {2}\n", strTime, Time.frameCount, condition);
            m_logBuilder.Append(log);
            m_logBuilder.Append(stackTrace);
            m_logBuilder.Append("\n");
            //m_logBuilder.Append("-xxx\n");
            //m_logBuilder.Append(GetStackTrace());
            Flush();
        }
    }

    private void Flush()
    {
        if (m_logBuilder.Length > 0 && enable)
        {
            //创建一个 StreamWriter,它将 UTF-8 编码文本追加到现有文件或新文件(如果指定文件不存在)。
            //https://docs.qq.com/sheet/DRGRsTXRVRmFWQkJM
            using (StreamWriter sw = File.AppendText(m_fullSaveFile))
            {
                sw.WriteLine(m_logBuilder.ToString());
            }
            //m_logBuilder.Remove(0, m_logBuilder.Length);
            // 从当前 StringBuilder 实例中移除所有字符。
            m_logBuilder.Clear();
        }
    }

    /// <summary>
    ///复制一份log,用来查找bug
    /// </summary>
    public void CopyOutPutLog()
    {
        try
        {
            if (File.Exists(m_fullSaveFile))
            {
                string file = File.ReadAllText(m_fullSaveFile);
                if (file.Length > 0)
                {
                    string copyFile = m_fullSaveFile.Replace("/outputlog.txt", "/outputlog_1.txt");
                    if (File.Exists(copyFile))
                    {
                        FileInfo copyFileInfo = new FileInfo(copyFile);
                        if (copyFileInfo.Length > MaxFileSize_1)
                        {
                            //创建一个新文件,使用指定编码向其中写入指定的字符串,然后关闭文件。 如果目标文件已存在,则覆盖该文件。
                            //https://docs.qq.com/sheet/DRGRsTXRVRmFWQkJM
                            File.WriteAllText(copyFile, string.Empty, Encoding.UTF8);
                        }
                    }

                    //打开一个文件,向其中追加指定的字符串,然后关闭该文件。 如果文件不存在,此方法将创建一个文件,将指定的字符串写入文件,然后关闭该文件。
                    //https://docs.qq.com/sheet/DRGRsTXRVRmFWQkJM
                    File.AppendAllText(copyFile, file);
                }
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError(e);
        }
    }

    public static Logger instance
    {
        get
        {
            if (s_instance == null)
            {
                lock (s_locker)
                {
                    if (s_instance == null)
                    {
                        s_instance = new Logger();
                    }
                }
            }

            return s_instance;
        }
    }

    private Logger()
    {
        m_logBuilder = new StringBuilder();
        m_logBuilder.Clear();
        enable = true;

        // 这里注意:注册Unity日记回调
        //Application.logMessageReceivedThreaded += logCallBack;
        Application.logMessageReceived += logCallBack;
    }

    public bool enable;
    private bool m_needUpload;
    private string m_fullSaveFile = string.Empty;
    private StringBuilder m_logBuilder;
    private static System.Object s_locker = new System.Object();
    private static Logger s_instance;

    private const long MaxFileSize = 0;
    private const long MaxFileSize_1 = 5 * 1024 * 1024;

    /// <summary>
    /// 获取调用堆栈信息
    /// </summary>
    private string GetStackTrace()
    {
        System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(true);
        string stackIndent = "";
        for (int i = 0; i < st.FrameCount; i++)
        {
            System.Diagnostics.StackFrame sf = st.GetFrame(i);

            //得到错误的方法
            stackIndent += sf.GetMethod() + "";
            //得到错误的文件名
            stackIndent += sf.GetFileName() + "";
            //得到文件错误的行号
            stackIndent += (":" + sf.GetFileLineNumber()) + "";
            //得到错误的列
            //stackIndent += " column:" + sf.GetFileColumnNumber() + " ";

            stackIndent += "\n";
        }
        return stackIndent;
    }
}

方法二:

using UnityEngine;
//using System.Collections;
using System.IO;

/// <summary>
/// 写文件
/// </summary>
public class WriteLog
{
    private string m_infoFile;

    private static readonly object s_lock = new object();
    private static WriteLog s_instance;
    public static WriteLog instance
    {
        get
        {
            if (s_instance == null)
            {
                lock (s_lock)
                {
                    if (s_instance == null)
                    {
                        s_instance = new WriteLog();
                    }
                }
            }
            return s_instance;
        }
    }

    private WriteLog()
    {
        Init();
    }

    private void Init()
    {
#if UNITY_EDITOR
        string dir = Application.dataPath;
        int index = dir.LastIndexOf("/");
        dir = dir.Substring(0, index);
        dir += "/GameLog";
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        m_infoFile = dir + "/" + "gamelog.txt";
#else
        string dir = string.Format("{0}/{1}", Application.persistentDataPath, "GameLog");
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        m_infoFile = dir + "/" + "gamelog.txt";
#endif
    }

    /// <summary>
    /// 获取调用堆栈信息
    /// </summary>
    private string GetStackTrace()
    {
        System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(true);
        string stackIndent = "";
        for (int i = 0; i < st.FrameCount; i++)
        {
            System.Diagnostics.StackFrame sf = st.GetFrame(i);

            //得到错误的方法
            stackIndent += sf.GetMethod() + "";
            //得到错误的文件名
            stackIndent += sf.GetFileName() + "";
            //得到文件错误的行号
            stackIndent += (":" + sf.GetFileLineNumber()) + "";
            //得到错误的列
            //stackIndent += " column:" + sf.GetFileColumnNumber() + " ";

            stackIndent += "\n";
        }
        return stackIndent;
    }

    /// <summary>
    /// 写入信息到本地文件
    /// </summary>
    /// <param name="info">信息</param>
    public void WriteInfo(string info)
    {
        using (StreamWriter sw = File.AppendText(m_infoFile))
        {
            //string stackInfo = new System.Diagnostics.StackTrace().ToString();
            string stackInfo = GetStackTrace();
            info += ("\n" + stackInfo);
            sw.WriteLine(info);
        }
    }
}

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity WebGL是一种用于在Web浏览器中运行Unity游戏的技术。由于WebGL的限制,Unity WebGL无法直接访问本地存储。但是,你可以使用PlayerPrefs和JsonUtility来实现在Unity WebGL中进行本地存储数据的功能。 PlayerPrefs是Unity提供的一个用于存储和访问玩家偏好设置的类。它可以用来保存和读取各种数据类型,包括整数、浮点数、字符串等。 JsonUtility是Unity提供的一个用于序列化和反序列化JSON数据的类。你可以使用JsonUtility将数据转换为JSON格式,并将其保存到PlayerPrefs中,然后在需要的时候再从PlayerPrefs中读取并反序列化为对象。 以下是一个示例代码,演示了如何在Unity WebGL中使用PlayerPrefs和JsonUtility实现本地存储数据的功能: ```csharp using UnityEngine; public class LocalStorageExample : MonoBehaviour { // 定义一个数据类 [System.Serializable] public class MyData { public int score; public string playerName; } void Start() { // 创建一个数据对象 MyData data = new MyData(); data.score = 100; data.playerName = "Player1"; // 将数据对象转换为JSON格式 string json = JsonUtility.ToJson(data); // 将JSON数据保存到PlayerPrefs中 PlayerPrefs.SetString("myData", json); // 从PlayerPrefs中读取JSON数据 string savedJson = PlayerPrefs.GetString("myData"); // 将JSON数据反序列化为数据对象 MyData savedData = JsonUtility.FromJson<MyData>(savedJson); // 输出读取到的数据 Debug.Log("Score: " + savedData.score); Debug.Log("Player Name: " + savedData.playerName); } } ``` 在上述示例中,我们定义了一个名为MyData的数据类,它包含一个整数类型的score和一个字符串类型的playerName。我们创建了一个MyData对象,并将其转换为JSON格式的字符串。然后,我们将JSON数据保存到PlayerPrefs中,并从PlayerPrefs中读取并反序列化为MyData对象。最后,我们输出读取到的数据。 请注意,由于Unity WebGL的限制,PlayerPrefs只能在WebGL的本地存储中保存少量数据。如果你需要保存大量数据,你可能需要考虑使用其他方法,如将数据发送到服务器进行存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值