ConsoleWindow中的双击日志定位
很多项目都有自己重写Debug.Log的习惯,难免会遇到在Unity的Console窗口中双击日志, 但是没法直接跳转到想要看到的代码那一行的时候,解决办法有以下2种:
- 将自己封装的日志类制作成DLL再导入到Unity使用,但是有时候想修改日志类的代码却比较麻烦了~~
- 使用本文提供的LogEditor类来自动定位!。!下面来详细说明下该类吧~~
使用方法:
- 将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)
- 在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类
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中的双击日志定位的更多相关文章
- SQL Server中的事务日志管理(9/9):监控事务日志
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- 使用SeasLog打造PHP项目中的高性能日志组件(一)
云智慧(北京)科技有限公司 高驰涛 什么是SeasLog SeasLog是一个C语言编写的PHP扩展,提供一组规范标准的功能函数,在PHP项目中方便.规范.高效地写日志,以及快速地读取和查询日志. 为 ...
- 把嵌入在eclipse中的tomcat日志分离出来
现象 不知道从哪个版本的tomcat开始,windows版本的tomcat不再包含{tomcat_home}\logs\catalina.out这个文件,eclipse中配置好tomcat服务器之后, ...
- C#中使用打印日志
在日常的工作中经常需要日志,这样能够很容易定位到代码中的一些错误,.Net中有自带的日志接口.并没有仔细去研究,这里是我自己写的日志接口,记录下来以便以后用到,根据时间打印相关的日志文件,代码如下: ...
- 在windows中:双击运行Python程序、后台运行Python程序
在windows中:双击运行Python程序.后台运行Python程序 安装Python解释器的windows环境,如果双击运行*.py的文件,会闪退.怎样避免闪退呢? 我们用python的日志输出程 ...
- SQL Server中的事务日志管理的阶梯,级别1:事务日志概述
SQL Server中的事务日志管理的阶梯,级别1:事务日志概述 翻译:刘琼滨 谢雪妮 许雅莉 赖慧芳 级别1:事务日志概述 事务日志是一个文件,其中SQL服务器存储了所有与日志文件关联的数据库执行的 ...
- Xcode8中处理打印日志的配置
Xcode8中处理打印日志的配置
- css中的大小、定位、轮廓相关属性
css中的大小.定位.轮廓相关属性 1.通过height.width属性控制组件大小 height:高度,可以设置任何有效的距离值: width:宽度,可以设置任何有效的属性值: max-height ...
- CSS中的浮动和定位
在了解CSS中的浮动和定位之前有必要先了解清楚标准流和脱离标准流的特性 标准流的默认特性 1.分行.块级元素,并且能够dispay转换. 2.块级元素(block):默认独占一行,不能并列显示,能够设 ...
随机推荐
- Count the Colors ZOJ - 1610 区间颜色覆盖
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> ...
- 修改sudoers
使用visudo命令 [root@898f990a8808 etc]# visudo
- Java,C 位移运算符 有符号右移>>与无符号右移>>>
个人博客 地址:https://www.wenhaofan.com/a/20181029232749 有符号右移 正数有符号右移 首先计算4>>2 将4转为二进制 0000 0100 右移 ...
- mac anyconnect 卸载方法
打开终端: 输入下面的命令 sudo /opt/cisco/vpn/bin/vpn_uninstall.sh 有问题 端口占用 sudo /opt/cisco/anyconnect/bin/webse ...
- PAT (Basic Level) Practice (中文)1057 数零壹 (20 分) (按行输入带空格的字符串)
给定一串长度不超过 1 的字符串,本题要求你将其中所有英文字母的序号(字母 a-z 对应序号 1-26,不分大小写)相加,得到整数 N,然后再分析一下 N 的二进制表示中有多少 0.多少 1.例如给定 ...
- Qt Gui 第五章绘图类
双缓冲 void Plotter::refreshPixmap() { pixmap = QPixmap(size()); pixmap.fill(, ); QPainter painter(& ...
- 记一个js toUpperCase函数 大小写特性
toUpperCase()是javascript中小写变大写的函数 "ı".toUpperCase() == 'I',"ſ".toUpperCase() == ...
- 13:IO流
IO简介 继承结构 整体架构 常用内容 分类 根据处理的数据单位不同,分为字节流和字符流:in/out相对于程序而言的输入(读取)和输出(写出)的过程,即根据数据的流向不同称为输入流和输出流 字符流的 ...
- 849. Dijkstra求最短路 I(模板)
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值. 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1. 输入格式 第一行包含整数n和m. 接下来m行每行包 ...
- 【vue 权威指南】 学习笔记 二
1.指令 1.1内部指令 基础指令:v-show , v-else , v-model , v-repeat , v-for , v-text , v-el , v-html , v-on , v-b ...