UnityEditor 控制台导出文本

开发过程中有时候需要保存控制台的内容,简短的内容可以截图,但是上百条的log信息就无能为力了,我们知道控制台有个功能可以打开控制台的txt文件

UnityEditor 控制台导出文本_第1张图片

但是要在里面找到想要的内容需要靠搜索,并且无关的内容很多。这里我分享一个项目中使用的小工具,可将控制台的内容全部导出到文本,并且可使用自带的筛选按钮筛选内容

直接贴代码:

//
// Copyright (c) 2018 Wayne Zheng
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
using System.IO;

public class ExportConsoleEditor : EditorWindow
{
    static Type _LogEntriesType;
    static Type _logEntryType;

    static MethodInfo _GetCountMethod;
    static MethodInfo _StartGettingEntriesMethod;
    static MethodInfo _GetEntryInternalMethod;
    static MethodInfo _EndGettingEntriesMethod;

    static FieldInfo _conditionField;

    static bool _isSupport = false;

    bool _detail = false;

    [MenuItem("Debug/Export Console")]
    static void ShowEditor()
    {
        ExportConsoleEditor editor = EditorWindow.GetWindowWithRect(new Rect(-1, -1, 170, 60), true, "Export Console", true);
        editor.Show();
    }

    [MenuItem("Debug/Export Console", validate = true)]
    static bool ExportConsoleMenuValidate()
    {
        return _isSupport && GetEntryCount() > 0;
    }

    private void OnGUI()
    {
        _detail = EditorGUILayout.Toggle("Detail", _detail);
        GUILayout.FlexibleSpace();
        if (GUILayout.Button("Export"))
        {
            if (DoExportConsole(_detail))
            {
                Close();
            }
        }
        GUILayout.Space(5);
    }

    
    static bool DoExportConsole(bool detail)
    {
        string[] logs = GetConsoleEntries();
        string path = EditorUtility.SaveFilePanel("Export Console", Application.dataPath, "ConsoleLog", "txt");
        if (string.IsNullOrEmpty(path))
        {
            return false;
        }

        if (!detail)
        {
            for (int i = 0; i < logs.Length; ++i)
            {
                using (var sr = new StringReader(logs[i]))
                {
                    logs[i] = sr.ReadLine();
                }                    
            }
        }
        File.WriteAllLines(path, logs);
        EditorUtility.OpenWithDefaultApp(path);
        return true;
    }

    static ExportConsoleEditor()
    {
        _LogEntriesType = Type.GetType("UnityEditor.LogEntries,UnityEditor");
        if (_LogEntriesType != null)
        {
            _GetCountMethod = _LogEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public);
            _StartGettingEntriesMethod = _LogEntriesType.GetMethod("StartGettingEntries", BindingFlags.Static | BindingFlags.Public);
            _GetEntryInternalMethod = _LogEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public);
            _EndGettingEntriesMethod = _LogEntriesType.GetMethod("EndGettingEntries", BindingFlags.Static | BindingFlags.Public);
        }

        _logEntryType = Type.GetType("UnityEditor.LogEntry,UnityEditor");
        if (_logEntryType != null)
        {
            _conditionField = _logEntryType.GetField("condition", BindingFlags.Public | BindingFlags.Instance);
        }
        CheckSupport();
    }

    static void CheckSupport()
    {
        if (_LogEntriesType == null ||
            _logEntryType == null ||
            _GetCountMethod == null ||
            _StartGettingEntriesMethod == null ||
            _GetEntryInternalMethod == null ||
            _EndGettingEntriesMethod == null ||
            _conditionField == null)
        {
            _isSupport = false;
        }
        else
        {
            _isSupport = true;
        }
    }

    static string[] GetConsoleEntries()
    {
        if (!_isSupport)
        {
            return null;
        }
        List entries = new List();

        object countObj = _GetCountMethod.Invoke(null, null);
        
        _StartGettingEntriesMethod.Invoke(null, null);
        
        int count = int.Parse(countObj.ToString());        
        for (int i = 0; i < count; ++i)
        {
            object logEntry = Activator.CreateInstance(_logEntryType);
            object result = _GetEntryInternalMethod.Invoke(null, new object[] { i, logEntry });
            if (bool.Parse(result.ToString()))
            {
                entries.Add(_conditionField.GetValue(logEntry).ToString());                
            }
        }        
        _EndGettingEntriesMethod.Invoke(null, null);
        return entries.ToArray();
    }

    static int GetEntryCount()
    {
        if (!_isSupport)
        {
            return 0;
        }
        object countObj = _GetCountMethod.Invoke(null, null);
        return int.Parse(countObj.ToString());
    }    
}

导入项目后,菜单处会新增按钮,点击后弹出窗口,Detail勾选后会导出详细的日志(堆栈信息)。

代码中使用反射得到了UnityEditor的控制台接口LogEntries,不同Unity版本可能有差异,如果接口名称有变化Export Console会不可点击。

点击Export后显示保存文件对话框

UnityEditor 控制台导出文本_第2张图片

到此就完成了控制台内容的导出。我这里只是抛砖引玉,更多复杂的功能读者可自行修改实现。


本博客还很年轻,会不时发布一些Unity开发经验和有用的框架组件。读者有任何问题都可以向作者提问,欢迎大家踊跃参与!大家的鞭笞是我成长的动力!谢谢!

你可能感兴趣的:(Unity,Tools)