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):默认独占一行,不能并列显示,能够设 ...
随机推荐
- Java中List的父类与子类如何转换?
目录 定义 要点: 子类转父类 父类转子类 定义 A是B的子类,A比B多几条属性 要点: A是B的子类,但List<A>不是List<B>的子类.所以想直接转换是不行的. 子类 ...
- BLOB-数据库中用来存储二进制文件的字段类型
BLOB (binary large object)----二进制大对象,是一个可以存储二进制文件的容器. 在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型. BLOB是一个大文件,典型 ...
- Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树
给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...
- PS_0002:改变曲线,改变色阶
1,ctrl + m 改变曲线 2,ctrl + l 改变色阶
- 【spring boot】SpringBoot初学(5)– WebService之Jersey
前言 github: https://github.com/vergilyn/SpringBootDemo 代码位置: 一.准备 spring boot对jersey1.x与jersey2.x的注入方 ...
- LeetCode-21 有序链表的合并
问题描述: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4输出:1->1-& ...
- 多线程模式下高并发的环境中唯一确保单例模式---DLC双端锁
DLC双端锁,CAS,ABA问题 一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会 ...
- py 二级习题(重新输出文本-----每行一句话)
#需要的一小段文本 txt = "人生得意须尽欢,莫使金樽空对月.天生我才必有用,千金散尽还复来." #对文本进行分割,转换成列表形式 def txt_split(txt): li ...
- (C语言)学生成绩排序-期末考倒数第二题结构体数组排序
假设学生的基本信息包括学号.姓名.三门课程成绩以及个人平均成绩,定义一个能够表示学生信息的结构类型.输入n(n<50)个学生的成绩信息,按照学生的个人平均分从高到低输出他们的信息.如果平均分相同 ...
- Linux vim三种模式的快捷键
1.移动光标 数字 + h,j,k,l 上,下,左,右 ctrl-e 移动页面 ctrl-f 上翻一页 ctrl-b 下翻一页 ctrl-u 上翻半页 ctrl-d 下翻半页 w 跳到下一个字首,按标 ...