【Unity Consoler Redirection】Unity Log 跳转重定向

Unity Log 跳转重定向

  • 为何要写这个重定向?
    • 开始

Hello大家好,这里VimalaEric,今天给大家介绍一个实用脚本 UnityConsoler 跳转重定向。

为何要写这个重定向?

因为有时候会自己写脚本打log,从而实现如输出不同的颜色、Release宏定义、 或者Debug.Log 要向服务器发送数据等。 有时候会自己写一个DebugExtension类,调用unity的Debug的同时封装一些我们需要的内容在上面。

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

开始

在开始之前,首先感谢 @神一般的狄狄 带来的思路。我也是在做公司架构的时候发现这个问题,遂找到了这篇文章。https://blog.csdn.net/qq_37776196/article/details/85324348

基本逻辑如其所示一般,然而在使用时我稍作改动。
1来兼容了对更深层Log的点击重定向。
2来增加了部分注释,微调了部分判断是否属于LogExtension 的逻辑。

将代码贴在下面,以供大家使用。

/** CopyRight By VimalaEric & Fox.Huang* 2024.4.28*/using UnityEngine;
using System;
using System.Reflection;
using System.Text.RegularExpressions;/// <summary>
/// Unity Log重定向。编辑器下,点击log跳转到代码位置
/// </summary>
public class ConsolerRedirection
{
#if UNITY_EDITOR/// <summary>/// 最大匹配检索深度/// </summary>private const int MaxRegexMatch = 20;// 处理asset打开的callback函数[UnityEditor.Callbacks.OnOpenAssetAttribute(0)]static bool OnOpenAsset(int instance, int line){// 自定义函数,用来获取stacktracestring stack_trace = GetStackTrace();// 通过stacktrace来判断是否是自定义Logif (!string.IsNullOrEmpty(stack_trace)){if (stack_trace.StartsWith("* "))//这里的“* ”是从堆栈中筛选自定义的Log{//匹配所有Log行Match matches = Regex.Match(stack_trace, @"\(at(.+)\)", RegexOptions.IgnoreCase);string pathline = "";if (matches.Success) {/* 找到跳转目标层:* 需要分别判断点击为首层还是其它层。* 首层时:跳过自定义Log层,向下一层跳转。* 其它层:直接跳转。*/if (matches.Groups[1].Value.EndsWith(line.ToString()))  //首层{matches = matches.NextMatch();}else{for (int i = 0; i < MaxRegexMatch; i++)             //其他层{if (matches.Groups[1].Value.EndsWith(line.ToString()))break;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 += 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的assemblyvar assembly_unity_editor = Assembly.GetAssembly(typeof(UnityEditor.EditorWindow));if (assembly_unity_editor == null) return null;// 找到类UnityEditor.ConsoleWindowvar type_console_window = assembly_unity_editor.GetType("UnityEditor.ConsoleWindow");if (type_console_window == null) return null;// 找到UnityEditor.ConsoleWindow中的成员ms_ConsoleWindowvar 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窗口时焦点窗口的话,获取stacktraceif ((object)UnityEditor.EditorWindow.focusedWindow == instance_console_window){// 通过assembly获取类ListViewStatevar type_list_view_state = assembly_unity_editor.GetType("UnityEditor.ListViewState");if (type_list_view_state == null) return null;// 找到类UnityEditor.ConsoleWindow中的成员m_ListViewvar 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_ActiveTextvar 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的值,就是我们需要的stacktracestring value_active_text = field_active_text.GetValue(instance_console_window).ToString();return value_active_text;}return null;}
#endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于python-flask技术的社区信息交流平台【数据库+15000文档】

预览 介绍 系统只需使用者通过电脑浏览器即可实现系统的访问和操作的WEB模式的信息化系统。为了保证系统数据的准确性、安全性的数据存储&#xff0c;系统应用MySQL数据库进行系统数据存储服务。根据对社区工作的深入调研和对社区居民的走访调查&#xff0c;详细分析整体系统的…

短信验证码绕过漏洞(一)

短信验证码绕过漏洞 0x01原理&#xff1a; 服务器端返回的相关参数作为最终登录凭证&#xff0c;导致可绕过登录限制。 危害&#xff1a;在相关业务中危害也不同&#xff0c;如找回密码&#xff0c;注册&#xff0c;电话换绑等地方即可形成高危漏洞&#xff0c;如果是一些普…

【VS+QT】visual studio 2022配置和搭建QT

一、下载QT 可以去QT官网下载:https://www.qt.io/product/development-tools。 直接安装。 二、安装qt插件 打开visual studio 2022&#xff0c;选择菜单栏中扩展->管理扩展 ,然后直接在vs插件市场搜索Qt Visual Studio Tools就行。 安装的时候根据提示&#xff0c;关闭…

YOLov5 + Gradio搭建简单的Web GUI

写在前面&#xff1a;当我们将模型训练出来了&#xff0c;此时就需要做UI界面给别人展示了。python提供的Gradio可以快速的搭建web页面。生成本地网址和公网网址&#xff0c;方面自己测试和用户测试。 一、安装 Gradio介绍 Gradio是一个开源的python库&#xff0c;用于构建机…

react完整项目搭建的思路

react完整项目搭建的思路 react完整项目搭建的思路1.使用creacte-react-app初始化项目2.安装所需插件:路由、网络、样式、组件库3.reactjs目录结构组织4. 配置路径别名4.配置路由5.网络配置,对axios进行封装》获取当前环境变量 6.配置代理解决跨域7.配置使用iconfont8.状态管理…

浅析扩散模型与图像生成【应用篇】(十七)——LDM

17. High-Resolution Image Synthesis with Latent Diffusion Models 该文首次提出在潜在特征空间中的扩散模型LDM&#xff0c;也是大名鼎鼎的Stable Diffusion&#xff08;SD&#xff09;模型的基础。不同于之前的扩散模型直接在图像维度上进行扩散和去噪&#xff0c;LDM首先训…

C++拷贝构造函数的合成

默认构造函数和拷贝构造函数在必要的时候才由编译期合成出来 文章目录 拷贝构造函数编译器合成拷贝构造函数的四种情况情况一 一个类有一个带有拷贝构造函数的类对象成员变量情况二 派生类的基类有一个拷贝构造函数类声明了一个或多个虚函数情况四 类派生自一个继承串联且有一个…

python在Django中,如何使用MySQL数据库进行分页怎么实现

在Django中,使用MySQL数据库进行分页是一个相对简单的任务。Django的ORM提供了内置的分页功能,你只需要使用Paginator类即可。以下是一个基本的示例,展示了如何在Django中使用MySQL进行分页: 首先,确保你已经安装了Django和MySQL,并且已经配置了Django项目以使用MySQL数…

[SQL系列]从零开始学Clickhouse

起因 听说2024年开始金三银四了&#xff0c;所以我和我的小伙伴们也抱着再去拿一些Offer的准备。但是一上来就蒙了&#xff0c;对方问&#xff0c;听说你对数据库非常熟悉&#xff0c;那就说说ClickHouse吧。 这怎么就不按套路出牌呢&#xff1f;不一般就问Mysql的InnoDB嘛。 赶…

利用机器学习进行图像分类:以TensorFlow和Keras为例

当使用 TensorFlow 和 Keras 进行图像分类时&#xff0c;常用的方法是使用卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;。以下是一个简单的图像分类示例&#xff0c;使用 TensorFlow 和 Keras 来训练一个 CNN 模型对手写数字进行分类。 …

JUC-并发编程19-定时任务定时线程池-ScheduledThreadPoolExecutor

1、结构图 2、初识 ScheduledThreadPoolExecutor用来处理延时任务或定时任务。 流程如下&#xff1a; 2.1 定时任务分为四种 如下&#xff1a; 未来执行一次的任务&#xff0c;无返回值&#xff1b; 未来执行一次的任务&#xff0c;有返回值&#xff1b; 未来按固定频率重复…

Linux基础 -- 跨平台原子操作:ARM 汇编与 C 语言集成

1. 汇编语言实现 首先&#xff0c;你需要用 ARM 汇编语言编写比较并交换的功能。这里以 ARMv8 架构为例&#xff0c;因为它直接支持 64 位操作&#xff0c;并且可以较容易地适配 32 位。 // cas.S // 实现 32 位和 64 位的比较并交换函数 .text .global cas32 .global cas64/…

安川YASKAWA机器人FS100控制箱维修全攻略

本文将一起探讨安川机器人控制箱维修和YASKAWA机械手FS100控制柜故障&#xff0c;从故障诊断到维修技巧。注意&#xff0c;在安川机械臂控制器FS100维修过程中&#xff0c;遇到复杂的问题&#xff0c;不要犹豫&#xff0c;及时联系子锐机器人&#xff0c;让您的机器人重获新生&…

chrome 安装devtools

chrome 安装devtools 下载安装 链接&#xff1a;https://github.com/vuejs/devtools 选择对应版本&#xff1a; 安装yarn 下载 npm install -g yarn --registryhttps://registry.npmmirror.com进入下载的目录安装依赖 yarn install --registryhttps://registry.npmmirror.…

一篇了解reactor框架特性

一篇了解reactor框架特性 本文档的一些典型的名词如下&#xff1a; Publisher&#xff08;发布者&#xff09;、Subscriber&#xff08;订阅者&#xff09;、Subscription&#xff08;订阅 n.&#xff09;、subscribe&#xff08;订阅 v.&#xff09;。event/signal&#xff0…

抖音 通用交易系统 下单 密钥生成

已PHP为例 前提提条件 必须在 linux 系统中 生成 准备工作 在小程序中 生成应用公匙 把生成的公匙 复制 在linux 系统中 创建文件 private_key.pem 并将公匙粘贴 接下来打开命令 执行命令即可 openssl genrsa -out private_key.pem 2048 rsa -in private_key.pem -pubo…

分治策略 --- 快排归并

目录 分治-快排 一、颜色分类 二、排序数组 三、数组中的第K个最大元素 四、库存管理 分治-归并 一、排序数组 二、交易逆序对的总数 三、计算右侧小于当前元素的个数 四、翻转对 分治是一种思想&#xff0c;也就是将大问题分解成小问题&#xff0c;一直分到小问题可…

【Camera KMD ISP SubSystem笔记】CAM SYNC与DRQ②

DRQ的作用&#xff1a; DRQ负责调度管理pipeline里的node处理逻辑(通过node之间的dependency依赖机制) 利用多线程并行处理Pipeline中并行的node&#xff0c;加快处理速度 DRQ运转流程&#xff1a; DRQ先告诉node fill dependency&#xff0c; 此时seq id 为0…

如何优雅的实现 iframe 多层级嵌套通讯

前言 在前端开发项目中&#xff0c;不可避免的总会和 iframe 进行打交道&#xff0c;我们通常会使用 postMessage 实现消息通讯。 如果存在下面情况&#xff1a; iframe 父子通讯iframe 同层级通讯iframe 嵌套层级通讯 当面对这种复杂的情况的时候&#xff0c;通讯不可避免…

Unity 物体触碰事件监听

声明委托 public delegate void MyDelegate(Collider trigger); C# 委托&#xff08;Delegate&#xff09; | 菜鸟教程 (runoob.com)https://www.runoob.com/csharp/csharp-delegate.html 定义委托 public MyDelegate onTriggerEnter; public MyDelegateonTriggerStay; pub…