Unity的Console窗口双击重新定向脚本。

time:20210909,说实话新版本的unity的console都已经把可以追踪的堆栈行,都列出来了。可以直接定位到。这篇文章其实已经没有意义了。但是这篇文章的内容,还是可以做学习之用。UnityEditor.Callbacks.OnOpenAssetAttribute的事件还是可以做其他用的。

Unity的Console窗口双击重新定向脚本。

因为有时候会自己写脚本 比如输出 Debug.Log 会有不同的颜色, 或者Debug.Log 要向服务器发送数据。 有时候不是用Application HandleLog的方法,会自己写一个DebugEx类,调用unity的Debug。

那么在 Console双击信息的时候,会定位到 Debug调用的位置,而不是 DebugEx调用的位置,这篇脚本 是做重新定位双击打开脚本位置的

附带一些注释。
引用了别人的一篇定位脚本,做了修改。。。引用了谁的已经不记得了。Sorry。

/*
 * By: Fox.Huang 黄文叶, Date:2018.12.18
 */
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;

public class DebugCodeLocation
{
#if UNITY_EDITOR
	// 处理asset打开的callback函数
	[UnityEditor.Callbacks.OnOpenAssetAttribute(0)]
	static bool OnOpenAsset(int instance, int line)
	{
		// 自定义函数,用来获取log中的stacktrace,定义在后面。
		string stack_trace = GetStackTrace();
		// 通过stacktrace来定位是否是我们自定义的log,我的log中有特殊文字[FoxLog],很好识别
		if (!string.IsNullOrEmpty(stack_trace))	// 可以自定义标签 在这里添加;原有代码混乱不做修改,需要自己定位;
		{
			string strLower = stack_trace.ToLower();
			if (strLower.Contains("[foxlog]"))
			{
				Match matches = Regex.Match(stack_trace, @"\(at(.+)\)", RegexOptions.IgnoreCase);
				string pathline = "";
				if (matches.Success)
				{
					pathline = matches.Groups[1].Value;
					matches = matches.NextMatch();	// 向上再提高一层 做进入;
					if (matches.Success)
					{
						pathline = matches.Groups[1].Value;
						pathline = pathline.Replace(" ", "");

						int split_index = pathline.LastIndexOf(":");
						string path = pathline.Substring(0, split_index);
						line = Convert.ToInt32(pathline.Substring(split_index + 1));
						string fullpath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets"));
						fullpath = fullpath + path;
						string strPath = fullpath.Replace('/', '\\');
						UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(strPath, line);
					}
					else
					{
						Debug.LogError("DebugCodeLocation OnOpenAsset, Error StackTrace");
					}

					matches = matches.NextMatch();
				}
				return true;
			}
		}
		return false;
	}

	static string GetStackTrace()
	{
		// 找到UnityEditor.EditorWindow的assembly
		var assembly_unity_editor = Assembly.GetAssembly(typeof(UnityEditor.EditorWindow));
		if (assembly_unity_editor == null) return null;

		// 找到类UnityEditor.ConsoleWindow
		var type_console_window = assembly_unity_editor.GetType("UnityEditor.ConsoleWindow");
		if (type_console_window == null) return null;
		// 找到UnityEditor.ConsoleWindow中的成员ms_ConsoleWindow
		var field_console_window = type_console_window.GetField("ms_ConsoleWindow", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
		if (field_console_window == null) return null;
		// 获取ms_ConsoleWindow的值
		var instance_console_window = field_console_window.GetValue(null);
		if (instance_console_window == null) return null;

		// 如果console窗口时焦点窗口的话,获取stacktrace
		if ((object)UnityEditor.EditorWindow.focusedWindow == instance_console_window)
		{
			// 通过assembly获取类ListViewState
			var type_list_view_state = assembly_unity_editor.GetType("UnityEditor.ListViewState");
			if (type_list_view_state == null) return null;

			// 找到类UnityEditor.ConsoleWindow中的成员m_ListView
			var field_list_view = type_console_window.GetField("m_ListView", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
			if (field_list_view == null) return null;

			// 获取m_ListView的值
			var value_list_view = field_list_view.GetValue(instance_console_window);
			if (value_list_view == null) return null;

			// 找到类UnityEditor.ConsoleWindow中的成员m_ActiveText
			var field_active_text = type_console_window.GetField("m_ActiveText", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
			if (field_active_text == null) return null;

			// 获得m_ActiveText的值,就是我们需要的stacktrace
			string value_active_text = field_active_text.GetValue(instance_console_window).ToString();
			return value_active_text;
		}

		return null;
	}
}
#endif
				matches = matches.NextMatch();	// 向上再提高一层 做进入;

这一行的作用是 选择你要的堆栈信息是哪一行

程序学无止尽。
欢迎大家沟通,有啥不明确的,或者不对的,也可以和我私聊
我的QQ 334524067 神一般的狄狄

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值