Unity 自定义Log系统

原因

1.测试跑IOS的时候,游戏卡死,但是却无法查看日志,因为必须将手机插在mac机器上,用xcode才能实时看日志。

2.Android虽然卡死后,可以再插上电脑,通过AndroidStudio查看已经输出的日志,但是也会遇到看不到日志,或者手机插上无法被ADB侦测的问题。

目标

1.让日志可以输出到3个地方:(1)控制台(2)界面 (3)文件

2.能输出游戏指定模块的日志

3.能输出特定级别的日志,如error,warning等

代码

注:UI组件YYUIWrapContent未贴上,如果需要使用,你们可以不使用输入到ui的功能。

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

public class DebugLog
{
    public enum OutputModule
    {
        eNone,
        ePve = 1,
        eWonderland = 2,
        eTrial = 3,
        eMainScene = 4,
        eUI = 5,
        eOther = 6,
        ePveBase = 7,
        eMiniGame = 8,
        eGM = 9,
        eProxy = 10,
        eLoader = 11,
        eBattle = 12,
        eResLoad = 13,
        eNetWork = 14,
        eStory = 15,
        ePlatform = 16,
    }

    public enum OutputTarget
    {
        eNone,
        eConsole = 1,
        eUI = 2,
        eFile = 3,
    }

    public enum OutputLevel
    {
        eNone,
        eLog = 1,
        eLogWaning = 2,
        eLogError = 3,
    }

    //全局控制是否开启日志
    public static bool isOpenLog;
    //控制输出的模块
    private static int outputModule;
    //控制输出的目标
    private static int outputTarget;
    //控制输出的等级
    private static int outputLevel;
    //文件路径
    private static string filePath;
    //ui显示最大缓存的日志数量
    private const int MAX_LOG_NUM = 1000;
    private static List<string> logList = new List<string>();
    //ui组件,实现循环滚动
    private static YYUIWarpContent wrapContent;

    public static void Init(YYUIWarpContent uiContent)
    {
        Application.logMessageReceived += LogCallback;

        //获取文件路径
        filePath = GetPath("LJSLogFile.txt");
        //删除已存在的文件
        if (File.Exists(filePath))
        {
            File.Delete(filePath);
        }
        //获取ui组件
        wrapContent = uiContent;
        //是否要输出日志
        isOpenLog = true;

        //指定要输出哪些模块
        SwitchModule(OutputModule.ePve, true);
        SwitchModule(OutputModule.eWonderland, true);
        SwitchModule(OutputModule.eTrial, true);
        SwitchModule(OutputModule.eMainScene, true);
        SwitchModule(OutputModule.eUI, true);
        SwitchModule(OutputModule.eOther, true);
        SwitchModule(OutputModule.ePveBase, true);
        SwitchModule(OutputModule.eMiniGame, true);
        SwitchModule(OutputModule.eGM, true);
        SwitchModule(OutputModule.eProxy, true);
        SwitchModule(OutputModule.eLoader, true);
        SwitchModule(OutputModule.eBattle, true);
        SwitchModule(OutputModule.eResLoad, true);
        SwitchModule(OutputModule.eNetWork, true);
        SwitchModule(OutputModule.eStory, true);
        SwitchModule(OutputModule.ePlatform, true);

        //指定要输出的目标
        SwitchTarget(OutputTarget.eConsole, true);
        SwitchTarget(OutputTarget.eUI, true);
        //SwitchTarget(OutputTarget.eFile, true);

        //指定输出的级别
        SwitchLevel(OutputLevel.eLog, true);
        SwitchLevel(OutputLevel.eLogWaning, true);
        SwitchLevel(OutputLevel.eLogError, true);

    }

    public static void LogCallback(string condition, string stackTrace, LogType type)
    {
        string result = "";
        if (type == LogType.Error || type == LogType.Log || type == LogType.Warning)
        {
            result = condition;
        }
        else
        {
            result = string.Format("{0}\n{1}", condition, stackTrace);
        }

        OutputUI(result);
        OutputFile(result);
    }

    public static void Log(OutputModule type, string message)
    {
        if (!IsOuputLog(type, OutputLevel.eLog))
        {
            return;
        }

        message = ModifyLog(message, 0);
        OutputConsole(message, 0);
    }

    public static void LogWarning(OutputModule type, string message)
    {
        if (!IsOuputLog(type, OutputLevel.eLogWaning))
        {
            return;
        }
 
        message = ModifyLog(message, 1);
        OutputConsole(message, 1);
    }

    public static void LogError(OutputModule type, string message)
    {
        if (!IsOuputLog(type, OutputLevel.eLogError))
        {
            return;
        }

        message = ModifyLog(message, 2);
        OutputConsole(message, 2);
    }

    private static void OutputConsole(string message, int type)
    {
        if(!IsOutputTarget(OutputTarget.eConsole))
        {
            return;
        }

        if (type == 0)
        {
            Debug.Log(message);
        }
        else if (type == 1)
        {
            Debug.LogWarning(message);
        }
        else if (type == 2)
        {
            Debug.LogError(message);
        }
    }

    private static void OutputFile(string message)
    {
        if (!IsOutputTarget(OutputTarget.eFile))
        {
            return;
        }

        FileStream fs = File.Open(filePath, FileMode.Append, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);
        sw.WriteLine(message);
        sw.Close();
        fs.Close();
    }

    private static void OutputUI(string message)
    {
        if (!IsOutputTarget(OutputTarget.eUI))
        {
            return;
        }

        if(logList.Count >= MAX_LOG_NUM)
        {
            logList.Clear();
        }
        logList.Add(message);
        wrapContent.Init(logList.Count, (obj, index) =>
        {
            Text text = obj.GetComponent<Text>();
            text.text = logList[index];
        }, null, false);
    }

    private static bool IsOuputLog(OutputModule type, OutputLevel level)
    {
        bool result = false;
        bool rule1 = (outputModule & (1 << (int)type)) > 0 ? true : false;
        bool rule2 = isOpenLog;
        bool rule3 = (outputLevel & (1 << (int)level)) > 0 ? true : false;
        if (rule1 && rule2 && rule3)
        {
            result = true;
        }

        return result;
    }

    private static bool IsOutputTarget(OutputTarget target)
    {
        bool result = false;
        result = (outputTarget & (1 << (int)target)) > 0 ? true : false;
        return result;
    }

    private static string ModifyLog(string message, int type)
    {
        string result = "";
        switch (type)
        {
            case 0:
                {
                    result += "common : ";
                }
                break;
            case 1:
                {
                    result += "warning : ";
                }
                break;
            case 2:
                {
                    result += "error : ";
                }
                break;
        }
        result += message;
        return result;
    }

    private static string GetPath(string name)
    {
        string path = "";
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
            case RuntimePlatform.IPhonePlayer:
                {
                    path = Application.persistentDataPath + "/" + name;
                }
                break;
            case RuntimePlatform.OSXEditor:
            case RuntimePlatform.WindowsEditor:
            case RuntimePlatform.WindowsPlayer:
                {
                    path = Application.dataPath + "/../" + name;
                }
                break;
        }

        return path;
    }

    public static void SwitchModule(OutputModule module, bool isOpen)
    {
        if (isOpen)
        {
            outputModule = outputModule | (1 << (int)module);
        }
        else
        {
            outputModule = outputModule & (~(1 << (int)module));
        }
    }

    public static void SwitchTarget(OutputTarget target, bool isOpen)
    {
        if(isOpen)
        {
            outputTarget = outputTarget | (1 << (int)target);
        }
        else
        {
            outputTarget = outputTarget & (~(1 << (int)target));
        }
    }

    public static void SwitchLevel(OutputLevel level, bool isOpen)
    {
        if (isOpen)
        {
            outputLevel = outputLevel | (1 << (int)level);
        }
        else
        {
            outputLevel = outputLevel & (~(1 << (int)level));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qweewqpkn/article/details/81673863