很多项目都有自己重写Debug.Log的习惯,难免会遇到在Unity的Console窗口中双击日志, 但是没法直接跳转到想要看到的代码那一行的时候,解决办法有以下2种:

  1. 将自己封装的日志类制作成DLL再导入到Unity使用,但是有时候想修改日志类的代码却比较麻烦了~~
  2. 使用本文提供的LogEditor类来自动定位!。!下面来详细说明下该类吧~~

使用方法:

  1. 将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)
  2. 在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类
 using System;
using System.Reflection;
using UnityEditor;
using UnityEngine; namespace shaco
{
public static class LogEditor
{
private class LogEditorConfig
{
public string logScriptPath = "";
public string logTypeName = "";
public int instanceID = ; public LogEditorConfig(string logScriptPath, System.Type logType)
{
this.logScriptPath = logScriptPath;
this.logTypeName = logType.FullName;
}
} //Add your custom Log class here
private static LogEditorConfig[] _logEditorConfig = new LogEditorConfig[]
{
new LogEditorConfig("Assets/shaco/Base/Scripts/Unity/Debug/Log.cs", typeof(shaco.Log)),
new LogEditorConfig("Assets/shaco/Base/Scripts/CSharp/Debug/Log.cs", typeof(shaco.Base.Log))
}; [UnityEditor.Callbacks.OnOpenAssetAttribute(-)]
private static bool OnOpenAsset(int instanceID, int line)
{
for (int i = _logEditorConfig.Length - ; i >= ; --i)
{
var configTmp = _logEditorConfig[i];
UpdateLogInstanceID(configTmp);
if (instanceID == configTmp.instanceID)
{
var statckTrack = GetStackTrace();
if (!string.IsNullOrEmpty(statckTrack))
{
var fileNames = statckTrack.Split('\n');
var fileName = GetCurrentFullFileName(fileNames);
var fileLine = LogFileNameToFileLine(fileName);
fileName = GetRealFileName(fileName); AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileName), fileLine);
return true;
}
break;
}
} return false;
} private static string GetStackTrace()
{
var consoleWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");
var fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
var consoleWindowInstance = fieldInfo.GetValue(null); if (null != consoleWindowInstance)
{
if ((object)EditorWindow.focusedWindow == consoleWindowInstance)
{
// Get ListViewState in ConsoleWindow
// var listViewStateType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ListViewState");
// fieldInfo = consoleWindowType.GetField("m_ListView", BindingFlags.Instance | BindingFlags.NonPublic);
// var listView = fieldInfo.GetValue(consoleWindowInstance); // Get row in listViewState
// fieldInfo = listViewStateType.GetField("row", BindingFlags.Instance | BindingFlags.Public);
// int row = (int)fieldInfo.GetValue(listView); // Get m_ActiveText in ConsoleWindow
fieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
string activeText = fieldInfo.GetValue(consoleWindowInstance).ToString(); return activeText;
}
}
return "";
} private static void UpdateLogInstanceID(LogEditorConfig config)
{
if (config.instanceID > )
{
return;
} var assetLoadTmp = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(config.logScriptPath);
if (null == assetLoadTmp)
{
throw new System.Exception("not find asset by path=" + config.logScriptPath);
}
config.instanceID = assetLoadTmp.GetInstanceID();
} private static string GetCurrentFullFileName(string[] fileNames)
{
string retValue = "";
int findIndex = -; for (int i = fileNames.Length - ; i >= ; --i)
{
bool isCustomLog = false;
for (int j = _logEditorConfig.Length - ; j >= ; --j)
{
if (fileNames[i].Contains(_logEditorConfig[j].logTypeName))
{
isCustomLog = true;
break;
}
}
if (isCustomLog)
{
findIndex = i;
break;
}
} if (findIndex >= && findIndex < fileNames.Length - )
{
retValue = fileNames[findIndex + ];
} return retValue;
} private static string GetRealFileName(string fileName)
{
int indexStart = fileName.IndexOf("(at ") + "(at ".Length;
int indexEnd = ParseFileLineStartIndex(fileName) - ; fileName = fileName.Substring(indexStart, indexEnd - indexStart);
return fileName;
} private static int LogFileNameToFileLine(string fileName)
{
int findIndex = ParseFileLineStartIndex(fileName);
string stringParseLine = "";
for (int i = findIndex; i < fileName.Length; ++i)
{
var charCheck = fileName[i];
if (!IsNumber(charCheck))
{
break;
}
else
{
stringParseLine += charCheck;
}
} return int.Parse(stringParseLine);
} private static int ParseFileLineStartIndex(string fileName)
{
int retValue = -;
for (int i = fileName.Length - ; i >= ; --i)
{
var charCheck = fileName[i];
bool isNumber = IsNumber(charCheck);
if (isNumber)
{
retValue = i;
}
else
{
if (retValue != -)
{
break;
}
}
}
return retValue;
} private static bool IsNumber(char c)
{
return c >= '' && c <= '';
}
}
}

本文为转载, 原文链接:https://blog.csdn.net/l449612236/article/details/76087616

ConsoleWindow中的双击日志定位的更多相关文章

  1. SQL Server中的事务日志管理(9/9):监控事务日志

    当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...

  2. 使用SeasLog打造PHP项目中的高性能日志组件(一)

    云智慧(北京)科技有限公司 高驰涛 什么是SeasLog SeasLog是一个C语言编写的PHP扩展,提供一组规范标准的功能函数,在PHP项目中方便.规范.高效地写日志,以及快速地读取和查询日志. 为 ...

  3. 把嵌入在eclipse中的tomcat日志分离出来

    现象 不知道从哪个版本的tomcat开始,windows版本的tomcat不再包含{tomcat_home}\logs\catalina.out这个文件,eclipse中配置好tomcat服务器之后, ...

  4. C#中使用打印日志

    在日常的工作中经常需要日志,这样能够很容易定位到代码中的一些错误,.Net中有自带的日志接口.并没有仔细去研究,这里是我自己写的日志接口,记录下来以便以后用到,根据时间打印相关的日志文件,代码如下: ...

  5. 在windows中:双击运行Python程序、后台运行Python程序

    在windows中:双击运行Python程序.后台运行Python程序 安装Python解释器的windows环境,如果双击运行*.py的文件,会闪退.怎样避免闪退呢? 我们用python的日志输出程 ...

  6. SQL Server中的事务日志管理的阶梯,级别1:事务日志概述

    SQL Server中的事务日志管理的阶梯,级别1:事务日志概述 翻译:刘琼滨 谢雪妮 许雅莉 赖慧芳 级别1:事务日志概述 事务日志是一个文件,其中SQL服务器存储了所有与日志文件关联的数据库执行的 ...

  7. Xcode8中处理打印日志的配置

    Xcode8中处理打印日志的配置

  8. css中的大小、定位、轮廓相关属性

    css中的大小.定位.轮廓相关属性 1.通过height.width属性控制组件大小 height:高度,可以设置任何有效的距离值: width:宽度,可以设置任何有效的属性值: max-height ...

  9. CSS中的浮动和定位

    在了解CSS中的浮动和定位之前有必要先了解清楚标准流和脱离标准流的特性 标准流的默认特性 1.分行.块级元素,并且能够dispay转换. 2.块级元素(block):默认独占一行,不能并列显示,能够设 ...

随机推荐

  1. 「JOI 2017 Final」绳

    题意 loj 做法 首先我们观察到最后能折起来的充要条件是: 只有两个颜色,除首尾外,所有颜色块内的数量为偶数 因为为偶数,我们进一步推论: 所有颜色块起始位置奇偶性相同 然后因为增与减都会有相同花费 ...

  2. TC SRM556 OldBridges

    题意 有一个包含\(n\)个点的图,点的编号分别为\(0\)到\(n-1\).有若干双向边连接两个点,有些边可以经过无限次,有些边最多只能经过(双向)两次.Alice计划从\(a1\)到\(a2\)进 ...

  3. P1525 关押罪犯【二分+二分图】

    输入输出样例 输入 #1 复制 4 6 1 4 2534 2 3 3512 1 2 28351 1 3 6618 2 4 1805 3 4 12884 思路 对于要求最大值最小的问题,不难想到二分. ...

  4. 怎样在GitHub上新建一个文件夹

    GitHub如何创建文件夹 创建新文件的时候名字后面加个斜杠(/)就可以了 点击新建文件,输入文件名的时候后面加上斜杠/就是创建了一个文件夹,没有斜杠就是创建了一个文 创建好后点提交 Commit n ...

  5. 42.Pycharm连接数据库出现错误:1045、1044:django.db.utils.OperationalError: (1045, "Access denied for user 'Whois'@'localhost' (using password: YES)”)

    1.在pycharm中设置好数据库的连接信息,连接数据库db01, DATABASES = { 'default': { # 指定所使用的的数据库引擎 'ENGINE': 'django.db.bac ...

  6. PIE-SDK For C++内存栅格数据的创建

    1.功能简介 目前在地理信息领域中数据包括矢量和栅格两种数据组织形式.每一种数据有不同的数据格式,目前PIE SDK支持多种数据格式的数据创建,下面对内存栅格数据格式的数据创建功能进行介绍. 2.功能 ...

  7. 已知float后几位,谋几位保留

    设变量n为float类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五入运算的表达式____. #include "common.h" #includ ...

  8. 【算法】用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

    public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer&g ...

  9. Docker造化钟神秀

    之前闲暇之余有玩过一哈Dokcer容器,但是日子挺久了,然后挺多东西就忘记了,趁着今天有时间重拾一下docker的相关知识. 搜索下载镜像 docker search ubuntu docker pu ...

  10. python 元组 列表 字典

    type()查看类型 //取整除 **幂 成员运算符: in  x在y序列中,就返回true 反之  not in 身份运算符: is is not 逻辑运算符 and or not 字符编码 问题 ...