Unity3D_移动端日志显示

本文介绍了在Unity3D开发移动端应用时,如何便捷地在设备上收集和查看日志,帮助开发者快速定位和解决问题。通过使用特定的调试工具或设置,可以在不借助电脑的情况下,直接在移动端看到程序运行的日志输出。
摘要由CSDN通过智能技术生成
#if UNITY_STANDALONE || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
//#define SAVE_ENABLED 注释保存日志文件自定义宏
#endif
#if ON_LOG
using System;
using UnityEngine;
using System.Collections.Generic;
using System.Collections.ObjectModel;

#if SAVE_ENABLED
using System.IO;
using System.Text;
#endif

//[AddComponentMenu("uLink Utilities/Console GUI")]
internal class uLinkConsoleGUIPro : MonoBehaviour
{
    [Serializable]
    public class LogMask
    {
        public bool message;
        public bool warning;
        public bool error;

        public LogMask() { }

        public LogMask(bool message, bool warning, bool error)
        {
            this.message = message;
            this.warning = warning;
            this.error = error;
        }

        public bool Filter(LogType type)
        {
            switch (type)
            {
                case LogType.Log: return message;
                case LogType.Warning: return warning;
                case LogType.Assert:
                case LogType.Exception:
                case LogType.Error: return error;
            }

            return true;
        }
    }

    private class CollapsedEntries : KeyedCollection<string, Entry>
    {
        protected override string GetKeyForItem(Entry entry)
        {
            return entry.key;
        }
    }

    private class Entry
    {
        public string key;
        public string log;
        public string logSpaced;
        public string stacktrace;
        public string stacktraceTabed;
        public LogType type;
        public bool expanded;
    }

    public enum Position
    {
        Bottom,
        Top,
    }

    public Position position = Position.Bottom;

    public LogMask captureLogMask = new LogMask { message = true, warning = true, error = true };
    public LogMask filterLogMask = new LogMask { message = true, warning = true, error = true };

    public int maxEntries = 1000;

    public int windowheight = 250;

    public KeyCode showByKey = KeyCode.F1;

    [SerializeField]
    private bool _isVisible = true;

    [SerializeField]
    /// <summary>
    /// Whether to open the window by shaking the device (mobile-only).
    /// </summary>
    private bool shakeToOpen = true;

    /// <summary>
    /// The (squared) acceleration above which the window should open.
    /// </summary>
    public float shakeAcceleration = 3f;

    public bool dontDestroyOnLoad = false;

    public GUISkin guiSkin = null;
    public int guiDepth = 0;

    public bool collapse = false;
    public bool autoScroll = true;
    public bool unlockCursorWhenVisible = true;

    private List<Entry> entries;
    private int messageCount;
    private int warningCount;
    private int errorCount;
    private Vector2 scrollPosition;
    private bool oldLockCursor;

    private static readonly Color[] typeColors =
    {
        Color.red,
        Color.magenta,
        Color.yellow,
        Color.white,
        Color.red
    };

    private const float WINDOW_MARGIN_X = 10;
    private const float WINDOW_MARGIN_Y = 10;

  
    int fontSize = 16;//默认字体大小16
    void Awake()
    {
        entries = new List<Entry>(maxEntries);

        if (_isVisible)
        {
            _isVisible = false;
            SetVisible(true);
        }
#if UNITY_5
        Application.logMessageReceived += CaptureLog;
#else
            Application.RegisterLogCallback(CaptureLog);
#endif
        windowheight = (int)(Screen.height * 0.98f);
    }

    void Update()
    {
        if (showByKey != KeyCode.None && Input.GetKeyDown(showByKey))
        {
            SetVisible(!_isVisible);
        }
        if(shakeToOpen&&Input.acceleration.sqrMagnitude> shakeAcceleration)
        {
            SetVisible(!_isVisible);
        }
    }

    void OnGUI()
    {
        if (!_isVisible) return;

        var oldSkin = GUI.skin;
        var oldDepth = GUI.depth;
        var oldColor = GUI.color;

        GUI.skin = guiSkin;
        GUI.depth = guiDepth;
        GUI.color = Color.white;

        float y = (position == Position.Bottom) ? Screen.height - windowheight - WINDOW_MARGIN_Y : WINDOW_MARGIN_Y;

        GUILayout.BeginArea(new Rect(WINDOW_MARGIN_X, y, Screen.width - WINDOW_MARGIN_X * 2, windowheight), GUI.skin.box);
        DrawGUI();
        GUILayout.EndArea();

        GUI.skin = oldSkin;
        GUI.depth = oldDepth;
        GUI.color = oldColor;
    }

    void DrawGUI()
    {
        var stackTraceLabelStyle = new GUIStyle(GUI.skin.box);
        stackTraceLabelStyle.alignment = TextAnchor.UpperLeft;
        stackTraceLabelStyle.fontSize = fontSize;
        GUILayoutOption[] gUILayoutOptions = new GUILayoutOption[] { GUILayout.MinWidth(60) ,GUILayout.MinHeight(30)};

        GUILayout.BeginVertical();

        GUILayout.BeginHorizontal();

        if (entries.Count == 0) GUI.enabled = false;

        if (GUILayout.Button("Clear", gUILayoutOptions))
        {
            Clear();
        }

        GUILayout.Space(5);

#if SAVE_ENABLED
        if (GUILayout.Button("Save",gUILayoutOptions))
        {
            Save();
        }

        GUILayout.Space(5);
#endif

        if (entries.Count == 0) GUI.enabled = true;

        collapse = GUILayout.Toggle(collapse, " Collapse", GUILayout.ExpandWidth(false));
        GUILayout.Space(5);

        autoScroll = GUILayout.Toggle(autoScroll, " Auto Scroll", GUILayout.ExpandWidth(false));
        GUILayout.Space(5);

        if(GUILayout.Button("FontSize +2",gUILayoutOptions))
        {
            ChangeFontSize( 2);
        }
        GUILayout.Space(5);

        if (GUILayout.Button("FontSize -2", gUILayoutOptions))
        {
            ChangeFontSize(-2);
        }
 
        GUILayout.FlexibleSpace();

        IEnumerable<Entry> drawEntries;
        int drawMessageCount;
        int drawWarningCount;
        int drawErrorCount;

        if (collapse)
        {
            var collapsedEntries = new CollapsedEntries();
            drawMessageCount = 0;
            drawWarningCount = 0;
            drawErrorCount = 0;

            for (int i = 0; i < entries.Count; i++)
            {
                var entry = entries[i];

                if (!collapsedEntries.Contains(entry.key))
                {
                    collapsedEntries.Add(entry);

                    switch (entry.type)
                    {
                        case LogType.Log: drawMessageCount++; break;
                        case LogType.Warning: drawWarningCount++; break;
                        case LogType.Assert:
                        case LogType.Exception:
                        case LogType.Error: drawErrorCount++; break;
                    }
                }
            }

            drawEntries = collapsedEntries;
        }
        else
        {
            drawEntries = entries;
            drawMessageCount = messageCount;
            drawWarningCount = warningCount;
            drawErrorCount = errorCount;
        }

        if (GUILayout.Button("Hide", gUILayoutOptions))
        {
            SetVisible(false);
        }

        GUI.color = typeColors[(int)LogType.Log];
        filterLogMask.message = GUILayout.Toggle(filterLogMask.message, " " + drawMessageCount + " Message(s)", GUILayout.ExpandWidth(false));
        GUI.color = Color.white;

        GUILayout.Space(5);

        GUI.color = typeColors[(int)LogType.Warning];
        filterLogMask.warning = GUILayout.Toggle(filterLogMask.warning, " " + drawWarningCount + " Warning(s)", GUILayout.ExpandWidth(false));
        GUI.color = Color.white;

        GUILayout.Space(5);

        GUI.color = typeColors[(int)LogType.Error];
        filterLogMask.error = GUILayout.Toggle(filterLogMask.error, " " + drawErrorCount + " Error(s)", GUILayout.ExpandWidth(false));
        GUI.color = Color.white;

        GUILayout.EndHorizontal();

        GUI.changed = false;
        scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUI.skin.box);
        if (GUI.changed) autoScroll = false;

        foreach (var entry in drawEntries)
        {
            if (filterLogMask.Filter(entry.type))
            {
                int typeIndex = (int)entry.type;
                GUI.color = (typeIndex < typeColors.Length) ? typeColors[typeIndex] : Color.white;
                
                GUI.changed = false;
                entry.expanded = GUILayout.Toggle(entry.expanded, entry.logSpaced, stackTraceLabelStyle, GUILayout.ExpandWidth(false) );
                if (GUI.changed) autoScroll = false;

                if (entry.expanded)
                {
                    GUILayoutOption[] gUILayoutOption = new GUILayoutOption[] { };
                    GUILayout.BeginHorizontal();
                    //GUILayout.Space(20);
                    GUILayout.Label(entry.stacktrace, stackTraceLabelStyle);
                    GUILayout.EndHorizontal();
                }
            }
        }

        GUILayout.EndScrollView();
        GUILayout.EndVertical();
    }

    public void SetVisible(bool visibility)
    {
        if (_isVisible == visibility) return;
        _isVisible = visibility;

        if (unlockCursorWhenVisible)
        {
            if (visibility)
            {
                oldLockCursor = Cursor.visible;
            }
            else
            {
                Cursor.visible = oldLockCursor;
            }
        }
    }
    void ChangeFontSize( int num)
    {
        fontSize += num;
        if (fontSize<10)
        {
            fontSize = 10;
        }
        else if(fontSize>50)
        {
            fontSize = 50;
        }
    }
    public void Clear()
    {
        entries.Clear();
        messageCount = 0;
        warningCount = 0;
        errorCount = 0;
    }

#if SAVE_ENABLED
    public void Save()
    {
        string gameinfo_name = "n";
        uint zoneidx = 0;
        string networkAddress = "0";
        int networkPort = 0;
        if (NetManagerBase.singleton != null)
        {
            NetManagerBase nm = (NetManagerBase.singleton as NetManagerBase);
            gameinfo_name = nm.gameinfo_name;
            zoneidx = nm.zoneidx;
            networkAddress = nm.networkAddress;
            networkPort = nm.networkPort;
        }

        var sb = new StringBuilder();
        for (int i = 0; i < entries.Count; i++)
        {
            var entry = entries[i];
            sb.AppendFormat("{{\"log_time\":\"{0:yyyy-MM-dd_HH.mm.ss}\", \"gameinfo_name\":\"{1}\", \"zoneidx\":{2}, \"networkAddress\":\"{3}\", \"networkPort\":{4}, \"log_type\":\"{5}\", \"log\":\"{6}\", \"stacktrace\":\"{7}\"}}",
                DateTime.Now, gameinfo_name, zoneidx, networkAddress, networkPort, entry.type, entry.log, entry.stacktraceTabed);
            sb.AppendLine();
        }
        entries.Clear();

        string filename = String.Format("C:\\mmo_log\\{0}_{1}_{2:yyyyMMdd}.log", zoneidx, networkPort, DateTime.Now);
        if (File.Exists(filename))
            File.AppendAllText(filename, sb.ToString());
        else
            File.WriteAllText(filename, sb.ToString());
    }
#endif

    void CaptureLog(string log, string stacktrace, LogType type)
    {
        if (!captureLogMask.Filter(type)) return;

        if (entries.Count == maxEntries)
        {
            var lastType = entries[0].type;
            entries.RemoveAt(0);

            switch (lastType)
            {
                case LogType.Log: messageCount--; break;
                case LogType.Warning: warningCount--; break;
                case LogType.Assert:
                case LogType.Exception:
                case LogType.Error: errorCount--; break;
            }
        }

        var stacktraceTabed = stacktrace;
        stacktrace = stacktrace.Trim('\n');
        var key = String.Format("{0}:{1}\n{2}", (int)type, log, stacktrace);
        var logSpaced = ' ' + log.Replace("\n", "\n ");

        if (logSpaced.Length > 1000)
        {
            logSpaced = logSpaced.Substring(0, 1000);
        }

        var entry = new Entry
        {
            key = key,
            log = log,
            logSpaced = logSpaced,
            stacktrace = stacktrace,
            stacktraceTabed = stacktraceTabed,
            type = type,
            expanded = false
        };

        entries.Add(entry);

        switch (type)
        {
            case LogType.Log: messageCount++; break;
            case LogType.Warning: warningCount++; break;
            case LogType.Assert:
            case LogType.Exception:
            case LogType.Error: errorCount++; break;
        }

        if (autoScroll) scrollPosition.y = float.MaxValue;

#if SAVE_ENABLED
        if (type == LogType.Exception || type == LogType.Error)
        {
            Save();
        }
#endif
    }
}
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值