欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UnityEditor 控制台导出文本

程序员文章站 2022-06-11 20:51:26
...

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

UnityEditor 控制台导出文本

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

直接贴代码:

//
// 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<ExportConsoleEditor>(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<string> entries = new List<string>();

        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());
    }    
}

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

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

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

UnityEditor 控制台导出文本

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


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

相关标签: Unity

上一篇: Libbson

下一篇: dbms_jobvsOracleScheduler