参考链接:
https://blog.csdn.net/qq_37776196/article/details/85324348
DebugCodeLocation.cs
1 using System.Reflection; 2 using UnityEngine; 3 4 public class DebugCodeLocation 5 { 6 #if UNITY_EDITOR 7 // 处理asset打开的callback函数 8 [UnityEditor.Callbacks.OnOpenAssetAttribute(0)] 9 static bool OnOpenAsset(int instance, int line) 10 { 11 string stack_trace = GetStackTrace(); 12 if (!string.IsNullOrEmpty(stack_trace)) 13 { 14 Debug.LogError("DebugCodeLocation:" + stack_trace); 15 return true; 16 } 17 return false; 18 } 19 20 static string GetStackTrace() 21 { 22 // 找到UnityEditor.EditorWindow的assembly 23 var assembly_unity_editor = Assembly.GetAssembly(typeof(UnityEditor.EditorWindow)); 24 if (assembly_unity_editor == null) return null; 25 26 // 找到类UnityEditor.ConsoleWindow 27 var type_console_window = assembly_unity_editor.GetType("UnityEditor.ConsoleWindow"); 28 if (type_console_window == null) return null; 29 // 找到UnityEditor.ConsoleWindow中的成员ms_ConsoleWindow 30 var field_console_window = type_console_window.GetField("ms_ConsoleWindow", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); 31 if (field_console_window == null) return null; 32 // 获取ms_ConsoleWindow的值 33 var instance_console_window = field_console_window.GetValue(null); 34 if (instance_console_window == null) return null; 35 36 // 如果console窗口时焦点窗口的话,获取stacktrace 37 if ((object)UnityEditor.EditorWindow.focusedWindow == instance_console_window) 38 { 39 // 通过assembly获取类ListViewState 40 var type_list_view_state = assembly_unity_editor.GetType("UnityEditor.ListViewState"); 41 if (type_list_view_state == null) return null; 42 43 // 找到类UnityEditor.ConsoleWindow中的成员m_ListView 44 var field_list_view = type_console_window.GetField("m_ListView", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 45 if (field_list_view == null) return null; 46 47 // 获取m_ListView的值 48 var value_list_view = field_list_view.GetValue(instance_console_window); 49 if (value_list_view == null) return null; 50 51 // 找到类UnityEditor.ConsoleWindow中的成员m_ActiveText 52 var field_active_text = type_console_window.GetField("m_ActiveText", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 53 if (field_active_text == null) return null; 54 55 // 获得m_ActiveText的值,就是我们需要的stacktrace 56 string value_active_text = field_active_text.GetValue(instance_console_window).ToString(); 57 return value_active_text; 58 } 59 60 return null; 61 } 62 } 63 #endif
效果如下(双击log就会打印其内容):
核心在于OnOpenAssetAttribute,其API介绍如下:
https://docs.unity3d.com/ScriptReference/Callbacks.OnOpenAssetAttribute.html
当在unity中双击打开一个资源就会回调方法,当返回true时表示已经对打开资源进行了处理;当返回false时表示会用一个外部工具打开资源(例如双击log打开调用脚本)
这个属性可以传入一个int型参数(起始为0),表示调用先后,例如OnOpenAssetAttribute(0)比OnOpenAssetAttribute(1)先调用