Unity自定义的日志双击定向跳转

1、通过反射来查找

using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

    internal sealed class LogIntercepter
    {
        private static LogIntercepter _current;
        private static LogIntercepter Current
        {
            get
            {
                if (_current == null)
                {
                    _current = new LogIntercepter();
                }
                return _current;
            }
        }

        private Type _consoleWindowType;
        private FieldInfo _activeTextInfo;
        private FieldInfo _consoleWindowInfo;
        private MethodInfo _setActiveEntry;
        private object[] _setActiveEntryArgs;
        private object _consoleWindow;

        private LogIntercepter()
        {
            _consoleWindowType = Type.GetType("UnityEditor.ConsoleWindow,UnityEditor");
            _activeTextInfo = _consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
            _consoleWindowInfo = _consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
            _setActiveEntry = _consoleWindowType.GetMethod("SetActiveEntry", BindingFlags.Instance | BindingFlags.NonPublic);
            _setActiveEntryArgs = new object[] { null };
        }

        [OnOpenAsset]
        private static bool OnOpenAsset(int instanceID, int line)
        {
            UnityEngine.Object instance = EditorUtility.InstanceIDToObject(instanceID);
            if (AssetDatabase.GetAssetOrScenePath(instance).EndsWith(".cs"))
            {
                return Current.OpenAsset();
            }
            return false;
        }

        private bool OpenAsset()
        {
            string stackTrace = GetStackTrace();
            if (stackTrace != "")
            {
                if (stackTrace.Contains("[日志.Info]") || stackTrace.Contains("[日志.Warning]") || stackTrace.Contains("[日志.Error]"))
                {
                    string[] paths = stackTrace.Split('
');
                    int index = 0;
                    for (int i = 0; i < paths.Length; i++)
                    {
                        if (paths[i].Contains(" (at "))
                        {
                            index += 1;

                            if (index == 2)
                            {
                                return OpenScriptAsset(paths[i]);
                            }
                        }
                    }
                }
            }
            return false;
        }

        private bool OpenScriptAsset(string path)
        {
            int startIndex = path.IndexOf(" (at ") + 5;
            int endIndex = path.IndexOf(".cs:") + 3;
            string filePath = path.Substring(startIndex, endIndex - startIndex);
            string lineStr = path.Substring(endIndex + 1, path.Length - endIndex - 2);

            TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(filePath);
            if (asset != null)
            {
                int line = 0;
                if (int.TryParse(lineStr, out line))
                {
                    object consoleWindow = GetConsoleWindow();
                    _setActiveEntry.Invoke(consoleWindow, _setActiveEntryArgs);

                    EditorGUIUtility.PingObject(asset);
                    AssetDatabase.OpenAsset(asset, line);
                    return true;
                }
            }
            return false;
        }
        
        private string GetStackTrace()
        {
            object consoleWindow = GetConsoleWindow();

            if (consoleWindow != null)
            {
                if (consoleWindow == EditorWindow.focusedWindow as object)
                {
                    object value = _activeTextInfo.GetValue(consoleWindow);
                    return value != null ? value.ToString() : "";
                }
            }
            return "";
        }

        private object GetConsoleWindow()
        {
            if (_consoleWindow == null)
            {
                _consoleWindow = _consoleWindowInfo.GetValue(null);
            }
            return _consoleWindow;
        }
    }

2、重写Log类

using UnityEngine;


/// <summary>
/// 日志工具箱
/// </summary>
public static class Log
{
    private static readonly string InfoPrefix = "<b><color=cyan>[日志.Info]</color></b> ";
    private static readonly string WarningPrefix = "<b><color=yellow>[日志.Warning]</color></b> ";
    private static readonly string ErrorPrefix = "<b><color=red>[日志.Error]</color></b> ";

    /// <summary>
    /// 打印信息日志
    /// </summary>
    /// <param name="content">日志内容</param>
    public static void Info(this string content)
    {
#if UNITY_EDITOR
        Debug.Log(InfoPrefix + content);
#else
            if (Main.Current.IsEnabledLogInfo)
            {
                Debug.Log(InfoPrefix + content);
            }
#endif
    }
    /// <summary>
    /// 打印警告日志
    /// </summary>
    /// <param name="content">日志内容</param>
    public static void Warning(this string content)
    {
#if UNITY_EDITOR
        Debug.LogWarning(WarningPrefix + content);
#else
            if (Main.Current.IsEnabledLogWarning)
            {
                Debug.LogWarning(WarningPrefix + content);
            }
#endif
    }
    /// <summary>
    /// 打印错误日志
    /// </summary>
    /// <param name="content">日志内容</param>
    public static void Error(this string content)
    {
#if UNITY_EDITOR
        Debug.LogError(ErrorPrefix + content);
#else
            if (Main.Current.IsEnabledLogError)
            {
                Debug.LogError(ErrorPrefix + content);
            }
#endif
    }
}

3、测试代码

using UnityEngine;public class NewBehaviourScript : MonoBehaviour {

    void Start () {
        Log.Info("-----");
    }
}

unity控制台:

 双击,跳转到

原文地址:https://www.cnblogs.com/Jason-c/p/13690403.html