当前位置: 首页 > news >正文

【Unity笔记】Unity 编辑器扩展:一键查找场景中组件引用关系(含完整源码)(组件引用查找工具实现笔记)

摘要:
本文介绍了如何在 Unity 编辑器中开发一款实用的编辑器扩展工具 —— ComponentReferenceFinder,用于查找场景中对某个自定义组件的引用关系。该工具特别适用于大型项目、多人协作或引入外部插件后,快速定位组件间的耦合关系。
本文从需求出发,逐步拆解功能目标:如何获取选中 GameObject、自定义组件的过滤逻辑、如何遍历场景中的 MonoBehaviour、反射字段和集合引用、解析 UnityEvent 中的持久化调用,以及如何在 EditorWindow 中呈现可视化查找结果。

在这里插入图片描述

前言


在 Unity 项目开发过程中,尤其当项目规模增大、多人协作或外部 SDK、DLL 插件引入后,我们常常遇到这样的需求:“我想知道某个 GameObject 上挂载的某个自定义组件,到底被场景中哪些脚本引用了?”。手工一个一个场景搜索、检查 Inspector,既容易漏掉隐式引用(数组、列表、UnityEvent),又耗时耗力。本文将从出发,以设计思路+关键代码片段的形式,记录如何一步步实现一款ComponentReferenceFinder 编辑器扩展工具,满足以下核心需求:

  1. Hierarchy 中选中一个 GameObject;
  2. 自动列出它挂载的所有“用户脚本”组件(包括自定义 DLL 插件中的 MonoBehaviour);
  3. 选择其中一个组件实例,点击“查找引用”按钮;
  4. 遍历场景(包含隐藏和 inactive)的所有 MonoBehaviour,反射查找字段引用、集合引用以及 UnityEvent 持久化引用;
  5. 将检索结果以可点击的列表形式呈现,支持点击“Ping”快速定位引用者;
  6. 在查找过程中显示可取消进度条,跳过 Unity 内部或未赋值字段,保证运行稳定。

一、需求拆解与功能规划

在动手编写工具之前,先把需求分解成几个清晰的子问题:

  1. 如何获取选中 GameObject
    利用 Selection.activeGameObject。当用户在层级面板切换选中对象后,插件要能自动响应并更新状态。

  2. 如何过滤“自定义组件”
    不是所有挂载在 GameObject 上的 MonoBehaviour 都要列出。我们只要项目中自己写的脚本,或通过第三方 DLL 引入的脚本组件,需要排除 Unity 自带的 TransformCameraLightParticleSystem,以及编辑器脚本等。

  3. 如何遍历场景中所有 MonoBehaviour
    Unity API 提供 Object.FindObjectsOfType<T>(true),可以同时检索包括 inactive 的全部场景物体。对每个物体,用 GetComponents<MonoBehaviour>() 枚举挂载的所有脚本。

  4. 如何检测字段引用
    利用反射(FieldInfo.GetValue)读取每个 MonoBehaviour 的所有实例字段(包括 public 和 private + [SerializeField])。如果字段值等于目标组件实例,则记录“单引用”。

  5. 如何检测集合引用
    当字段类型实现了 IEnumerable(排除 string),则将其强转为 IEnumerable,对其中每个元素判断是否引用目标组件;若命中则记录“集合引用”。

  6. 如何检测 UnityEvent 引用
    UnityEvent 在 Inspector 上配置的回调保存于序列化属性 m_PersistentCalls.m_Calls。借助 SerializedObjectSerializedProperty,可以读取这些持久化数据,从中找到 m_Target 字段等于目标组件的调用列表。

  7. 如何呈现结果并支持定位
    EditorWindow.OnGUI 方法中,使用滚动视图 (EditorGUILayout.BeginScrollView) 列出每一条引用记录,并为每条记录生成一个“Ping”按钮,点击后调用 EditorGUIUtility.PingObject(GameObject),在层级面板中高亮对应引用对象。


二、核心组件设计

2.1 主窗口类:ComponentReferenceFinder

  • 继承自 EditorWindow
  • 挂载菜单项 MenuItem("Tools/Component Ref Finder")
  • 关键字段:
    • GameObject selectedObject:当前选中物体;
    • MonoBehaviour[] customScripts:选中物体上的自定义脚本组件列表;
    • int selectedScriptIndex:下拉选择索引;
    • List<ReferenceResult> results:存放所有查找到的引用记录;
    • Vector2 scrollPos:滚动视图位置。

2.2 引用记录结构:ReferenceResult

用来封装一条引用信息,包括:

  • GameObject referencingObject:引用目标组件的 GameObject;
  • MonoBehaviour hostComponent:哪条脚本组件里的字段或 UnityEvent 产生了引用;
  • string fieldName:字段名;
  • bool isCollection:是否集合类型引用;
  • bool isUnityEvent:是否 UnityEvent 引用。

这个结构便于在 GUI 中统一渲染和处理点击事件。


三、实现步骤

下面从高到低,逐步拆解每一步的实现要点,并给出关键代码示例。

3.1 窗口初始化与选中物体监听

[MenuItem("Tools/Component Ref Finder")]
public static void ShowWindow() {GetWindow<ComponentReferenceFinder>("Component Ref Finder");
}private void OnSelectionChange() {// 每当层级中选中对象变化时,重置状态并重绘窗口selectedScriptIndex = 0;results.Clear();Repaint();
}
  • ShowWindow:将插件挂到 Tools 菜单;
  • OnSelectionChange:Unity 编辑器回调,选中改变时重置索引、清空结果,并调用 Repaint()OnGUI 重新绘制。

3.2 枚举自定义组件下拉列表

OnGUI 中:

selectedObject = Selection.activeGameObject;
if (selectedObject == null) {EditorGUILayout.HelpBox("请先在场景中选中一个对象!", MessageType.Warning);return;
}customScripts = selectedObject.GetComponents<MonoBehaviour>().Where(c => c != null && IsUserScript(c.GetType())).ToArray();if (customScripts.Length == 0) {EditorGUILayout.HelpBox("该对象没有自定义脚本组件", MessageType.Info);return;
}// 下拉选择
string[] scriptNames = customScripts.Select(c => c.GetType().FullName).ToArray();
selectedScriptIndex = EditorGUILayout.Popup("组件类型", selectedScriptIndex, scriptNames);
  • IsUserScript(Type t):根据脚本所属程序集名称过滤,只保留自定义 DLL/Assembly。
  • Popup 生成下拉框,用户可选择要查找引用的组件实例。

3.3 遍历场景并查找字段引用

核心查找方法 FindReferencesToComponent

private void FindReferencesToComponent(MonoBehaviour targetComp) {results.Clear();var allObjs = GameObject.FindObjectsOfType<GameObject>(true);int total = allObjs.Length, processed = 0;foreach (var obj in allObjs) {processed++;if ( EditorUtility.DisplayCancelableProgressBar("查找引用中...", obj.name, (float)processed/total) )break;if (!obj.scene.IsValid()) continue;foreach (var comp in obj.GetComponents<MonoBehaviour>()) {if (comp == null || !IsUserScript(comp.GetType())) continue;var fields = comp.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);foreach (var field in fields) {object value = null;try { value = field.GetValue(comp); }catch { continue; }    // 安全跳过// 单个引用if ( ReferenceEquals(value, targetComp) ) {results.Add(new ReferenceResult(obj, comp, field.Name, false, false));continue;}// 集合引用if (typeof(IEnumerable).IsAssignableFrom(field.FieldType)&& field.FieldType != typeof(string)){var ie = value as IEnumerable;if (ie != null) {try {foreach (var item in ie) {if ( ReferenceEquals(item, targetComp) ) {results.Add(new ReferenceResult(obj, comp, field.Name, true, false));break;}}}catch { }}}// UnityEvent 引用检测(下节示例)}}}EditorUtility.ClearProgressBar();
}
  • ProgressBar:调用 DisplayCancelableProgressBar,提示当前物体名,并支持用户取消搜索。
  • 跳过无效场景对象:判断 obj.scene.IsValid(),过滤 prefab 等资源。
  • 字段反射GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 获取所有实例字段。
  • 引用判断:使用 ReferenceEquals,确保比对的是实例引用而不是值类型或重写了 Equals 的逻辑。
  • 集合处理:先判断类型可枚举,再强转并在 try-catch 中遍历,避免内部未赋值导致崩溃。

3.4 持久化 UnityEvent 调试

UnityEvent 底层结构如下(简化):

UnityEventBase└─ PersistentCalls m_PersistentCalls└─ List<PersistentCall> m_Calls└─ PersistentCall├─ Object m_Target├─ string m_MethodName└─ …...

要查找 UnityEvent 引用,需要:

  1. 新建 SerializedObject so = new SerializedObject(comp);
  2. var prop = so.FindProperty(field.Name);
  3. var calls = prop.FindPropertyRelative("m_PersistentCalls.m_Calls");
  4. 遍历 calls.arraySize,取出每个 m_Target 属性,比对是否等于目标组件:
if (typeof(UnityEventBase).IsAssignableFrom(field.FieldType)) {try {var so = new SerializedObject(comp);var prop = so.FindProperty(field.Name);var calls = prop.FindPropertyRelative("m_PersistentCalls.m_Calls");if (calls != null && calls.isArray) {for (int i = 0; i < calls.arraySize; i++) {var call = calls.GetArrayElementAtIndex(i);var targetProp = call.FindPropertyRelative("m_Target");if (targetProp != null &&targetProp.objectReferenceValue == targetComp) {results.Add(new ReferenceResult(obj, comp, field.Name, false, true));break;}}}}catch { }
}
  • 注意:序列化属性访问也要用 try-catch 包裹,以防 Unity 内部或私有字段访问异常。

3.5 完整代码

下载地址


四、使用步骤

  1. 安装脚本

    • ComponentReferenceFinder.cs 放到项目的 Assets/Editor/ 目录下。
  2. 打开窗口

    • 在 Unity 顶部菜单栏依次点击:
      Tools -> ExTool-> Component Ref Finder
      
  3. 选中目标 GameObject

    • Hierarchy 面板中点击你要排查的场景物体 A。
    • 确保它是场景实例(而非 Prefab 资源文件)。
      在这里插入图片描述
  4. 选择组件实例

    • 窗口中会列出 A 上所有“用户脚本”组件(包括自定义 DLL 中的 MonoBehaviour)。
    • 从下拉框中选择你关心的那个组件(例如 SoundEffectsPlayer)。
      在这里插入图片描述
  5. 执行检索

    • 点击 “查找引用该组件的对象” 按钮。
    • 窗口底部将出现一个进度条,显示当前正在扫描的 GameObject 名称。
    • 在大场景中,你可以随时按 Esc 或点击进度条的取消按钮中断搜索。
      在这里插入图片描述
  6. 查看与定位结果

    • 检索完成后,底部列表会展示所有引用该组件实例的记录,包括:
      • 单字段引用
      • 集合引用(List/Array)
      • UnityEvent 持久化引用
    • 每条记录前有一个 “Ping” 按钮:
      • 点击即可在 Hierarchy 中高亮并聚焦对应的引用 GameObject。
        在这里插入图片描述
  7. 后续排查

    • 找到引用后,双击打开对应脚本或在 Inspector 中检查字段,进一步定位用途与调用逻辑。
    • 若发现误引用或不再需要的回调,将其清理或重构,以保持场景引用关系的清晰。

五、优化与扩展方向

5.1 优化内容

  • 跳过 Unity 内部脚本:在 IsUserScript(Type t) 中排除 UnityEngine.*UnityEditor.*System.* 等程序集,减少无关反射开销。
  • catch 屏蔽:对所有反射、枚举、序列化操作进行 try-catch,只跳过当前字段或组件,不影响整体搜索进程。
  • 进度条:分批刷新,避免一次性满帧卡死。

5.2 扩展方向

  1. 链式引用:支持递归查找 A → B → C,识别多级引用关系,并以树状结构展示;
  2. 场景快照对比:记录不同场景版本之间的引用差异,帮助回归测试;
  3. 导出报告:将结果保存为 JSON、CSV 或 Markdown 文档,便于团队共享;
  4. 代码静态分析集成:结合 Mono.Cecil、Roslyn,定位脚本中对组件方法(如 .Play())的调用;
  5. 上下文菜单:在 Inspector 中右键某组件,当选时直接调用查找工具。

六、结语

本文以需求驱动的方式,记录了从零构思到实现一个通用的 Unity 编辑器扩展——ComponentReferenceFinder 的全过程。它不仅能满足字段级引用查找,还兼顾集合和 UnityEvent 的场景,适配自定义 DLL 和大型多人项目。

把它集成到你的项目中,可以大幅提升定位隐式依赖、排查丢失引用、管理复杂组件关系的效率。希望这篇笔记能帮助你快速掌握 Unity 编辑器扩展与反射、序列化属性的组合使用思路,从而更好地构建属于自己团队的开发工具链。

欢迎在评论区分享你的使用体验与改进想法!

相关文章:

【Unity笔记】Unity 编辑器扩展:一键查找场景中组件引用关系(含完整源码)(组件引用查找工具实现笔记)

摘要&#xff1a; 本文介绍了如何在 Unity 编辑器中开发一款实用的编辑器扩展工具 —— ComponentReferenceFinder&#xff0c;用于查找场景中对某个自定义组件的引用关系。该工具特别适用于大型项目、多人协作或引入外部插件后&#xff0c;快速定位组件间的耦合关系。 本文从需…...

实体店的小程序转型之路:拥抱新零售的密码-中小企实战运营和营销工作室博客

实体店的小程序转型之路&#xff1a;拥抱新零售的密码-中小企实战运营和营销工作室博客 在当今数字化浪潮的冲击下&#xff0c;实体店面临着前所未有的挑战&#xff0c;但小程序的出现为实体店转型新零售带来了新的曙光。先来看一组惊人的数据&#xff0c;据相关统计&#xff…...

Mysql安装与备份配置分析

若之前存有msqyl的数据缓存&#xff0c;建议用以下命令将数据文件删除干净 mysql-server&#xff1a;主程序 mysql&#xff1a;客户端工具 mysql-devel&#xff1a;开发库 mysql-libs&#xff1a;共享库文件 /var/lib/mysql&#xff1a;数据目录 /etc/my.cnf : 主配置文件 …...

Android APP 爬虫操作

工具 夜神模拟器、charles、mitm 等 mitm的使用参考:Mitmproxy对Android进行抓包&#xff08;真机&#xff09;_mitmproxy 安卓-CSDN博客 charles的使用参考&#xff1a;【全网最详细】手把手教学Charles抓包工具详细自学教程&#xff0c;完整版安装教程&#xff0c;详细介绍…...

与Ubuntu相关命令

windows将文件传输到Ubuntu 传输文件夹或文件 scp -r 本地文件夹或文件 ubuntu用户名IP地址:要传输到的文件夹路径 例如&#xff1a; scp -r .\04.py gao192.168.248.129:/home/gao 如果传输文件也可以去掉-r 安装软件 sudo apt-get update 更新软件包列表 sudo apt insta…...

Unity常用内置变换矩阵

Unity引擎提供了一系列内置的变换矩阵&#xff0c;这些矩阵在着色器中用于处理物体、摄像机和光照的坐标变换&#xff0c;是游戏开发中不可或缺的工具。它们帮助开发者在顶点着色器和片段着色器中实现坐标转换、光照计算等功能。 主要变换矩阵类型 模型矩阵 (Model Matrix) /…...

算法题-图论

图的表示 207.课程表 127.单词接龙 图的遍历 DFS 递归。。。 200.岛屿数量 239.矩阵中的最长递增路径 BFS 102.二叉树的层序遍历 看到最短&#xff0c;首先想到的是BFS 542.01矩阵 207.课程表 127.单词接龙 拓扑排序 对于一个有向无环图G进行拓扑排序&#xff0c;是将G中…...

Java 8(Ubuntu 18.04.6 LTS)安装笔记

一、前言 本文与【MySQL 8&#xff08;Ubuntu 18.04.6 LTS&#xff09;安装笔记】同批次&#xff1a;先搭建数据库&#xff0c;再安装JVM&#xff0c;后面肯定就是部署Web应用了——典型的单机部署&#xff0c;真可谓“麻雀虽小五脏俱全”。 二、准备 &#xff08;1&#xff…...

unity编辑器的json验证及格式化

UNITY编辑器的json格式化和验证工具资源-CSDN文库https://download.csdn.net/download/qq_38655924/90676188?spm1001.2014.3001.5501 反复去别的网站验证json太麻烦了 用这个工具能方便点 # Unity JSON工具 这是一个Unity编辑器扩展&#xff0c;用于验证、格式化和压缩JSO…...

C语言中小写字母转大写字母

一、题目引入 这一题运行结果是什么? 二、代码分析 在这个代码中 首先 -> 定义了一个字符数组空间内存是80 里面存储的是字符串123abcdEFG*& 接着 -> 定义了一个整型变量j 后面的循环会用到 然后 -> 使用了<stdio.h>中的库函数puts(ch)原样打印…...

深度学习--卷积神经网络调整学习率

文章目录 前言一、学习率1、什么学习率2、什么是调整学习率3、目的 二、调整方法1、有序调整1&#xff09;有序调整StepLR(等间隔调整学习率)2&#xff09;有序调整MultiStepLR(多间隔调整学习率)3&#xff09;有序调整ExponentialLR (指数衰减调整学习率)4&#xff09;有序调整…...

桥接模式:分离抽象与实现的独立进化

桥接模式&#xff1a;分离抽象与实现的独立进化 一、模式核心&#xff1a;解耦抽象与实现的多层变化 在软件设计中&#xff0c;当抽象&#xff08;如 “手机品牌”&#xff09;和实现&#xff08;如 “操作系统”&#xff09;都可能独立变化时&#xff0c;使用多层继承会导致…...

配置kafka与spark连接

一、配置kafka 首先进到software目录当中&#xff0c;如下图所示&#xff1a; 安装包上传/解压/重命名/解压过后的目录如下图所示&#xff1a; 修改配置&#xff1a; cd config vi server.properties 全部修改语句如下所示&#xff08;以node01为样例&#xff09;&#xff1…...

WebXR教学 05 项目3 太空飞船小游戏

准备工作 自动创建 package.json 文件 npm init -y 安装Three.js 3D 图形库&#xff0c;安装现代前端构建工具Vite&#xff08;用于开发/打包&#xff09; npm install three vite 启动 Vite 开发服务器&#xff08;推荐&#xff09;&#xff08;正式项目开发&#xff09; …...

【leetcode】3524 求出数组的X值1

题目链接 题目描述 给你一个正整数数组 nums 和一个正整数 k。 你可以对数组执行一次操作&#xff1a;移除不重叠的前缀和后缀&#xff08;可以为空&#xff09;&#xff0c;留下一个连续非空子数组。 对于每一种留下的子数组&#xff0c;计算&#xff1a; (该子数组的乘积…...

配电室安全用电漏电保护装置的安全用电措施

配电室作为电力分配与控制的关键场所&#xff0c;其安全用电装置的重要性不言而喻。 防触电、防漏电、防火灾、安全防护、保障生命财产&#xff1b; 当用电设备发生短路、过载或漏电等异常时能迅速切断电源&#xff0c;精准定位问题。及时报警&#xff0c;防止触电 在配电室中…...

数据库-基本概述 和 SQL 语言

标题目录 基本概述DB和DBMS关系数据库库与表的概念表库 数据库在项目中的角色如何操作数据库 SQL 语言SQL 分类DDL 语言数据库操作创建数据库查看数据库删除数据库切换数据库 表的操作创建表查看表修改表名删除表修改表结构 DML 语言插入数据修改数据删除数据 基本概述 DB和DB…...

C语言中的递归1.0

一、递归函数概念引入 简单来说就是自己调用自己 递归函数满足的两个条件: 1.每次调用函数本身,必须一次又一次接近最终结果 2.必须有停止条件 二、代码展示 用递归求1到4的和 代码如下 三、代码分析 首先进入main主函数入口 int sum getsum(4); 就这个具体题目来看 我…...

解锁webpack:对html、css、js及图片资源的抽离打包处理

面试被问到webpack&#xff0c;可别只知道说 HtmlWebpackPlugin 了哇。 前期准备 安装依赖 npm init -y npm install webpack webpack-cli --save-dev配置打包命令 // package.json {"scripts": {// ... 其他配置信息"build": "webpack --mode pr…...

[特殊字符] 大模型对话风格微调项目实战——模型篇 [特殊字符]✨

&#x1f4dc; 目录 &#x1f3af; 背景介绍 &#x1f50d; 这篇文章的任务 &#x1f916; 模型选型 &#x1f4ca; 模型评测 ⚙️ 模型训练 &#x1f504; 模型转换 &#x1f9ea; 模型训练效果评估 &#x1f389; 总结 &#x1f3af; 背景介绍 本文是《大模型对话风…...

lerobot[act解析]

ACT是具身智能模仿学习中重要的一个算法&#xff0c;本文会先从这个算法是是什么&#xff0c;这个算法如何工作的&#xff0c;到这个算法为什么有效&#xff0c;也就是what->how->why的这么一个顺序来进行解析 ACT 是什么&#xff1f;&#xff08;What&#xff09; 核心…...

使用Python创建带边框样式的Word表格

引言 在生成Word文档时&#xff0c;表格的边框样式是提升专业度的重要细节。本文将通过一个实例&#xff0c;展示如何使用python-docx库为表格添加上下边框加粗和内部边框隐藏的复杂样式。代码将实现以下效果&#xff1a; 表格位于页面底部表格首行和末行的上下边框加粗隐藏内…...

GPLT-2025年第十届团体程序设计天梯赛总决赛题解(共计266分)

今天偶然发现天梯赛的代码还保存着&#xff0c;于是决定写下这篇题解&#xff0c;也算是复盘一下了 L1本来是打算写的稳妥点&#xff0c;最后在L1-6又想省时间&#xff0c;又忘记了insert&#xff0c;replace这些方法怎么用&#xff0c;也不想花时间写一个文件测试&#xff0c…...

基于SpringBoot的课程管理系统

前言 今天给大家分享一个基于SpringBoot的课程管理系统。 1 系统介绍 课程管理系统是一种专门为学校设计的软件系统&#xff0c;旨在帮助学校高效地管理和组织各类课程信息。 该系统通常包括学生、教师和管理员三大角色。 他们可以通过系统进行选课、查看课程表、考试、进…...

新品发布 | 6 秒全谱成像,VIX-N320 内置推扫式高光谱相机重磅发布

深圳市中达瑞和科技有限公司正式发布全新一代VIX-N320内置推扫式可见光近红外高光谱相机&#xff0c;一款集高速成像、高精度光谱分析与便携性于一体的革命性产品。以突破性技术重新定义光谱成像效率与精度&#xff0c;开启智能感知新纪元。作为国内唯一同时掌握凝采式、推扫式…...

手写深拷贝函数

在 JavaScript 中&#xff0c;深拷贝是指创建一个对象或数组的完全独立副本&#xff0c;包括其嵌套的对象或数组。这意味着修改副本不会影响原始对象。 以下是手写一个通用的深拷贝函数的实现&#xff1a; 深拷贝函数实现 function deepClone(target, map new WeakMap()) {//…...

智能电网第3期 | 配电房巡检机器人通信升级方案

随着电力系统智能化发展&#xff0c;配电房巡检机器人是保障电力设备安全稳定运行的重要工具&#xff0c;其通信稳定性关乎巡检效率与质量。配电房巡检智能化升级面临着多项挑战&#xff1a; 电磁干扰大&#xff1a;配电房电气设备密集&#xff0c;电磁干扰强&#xff0c;易造成…...

阿里云 AI 搜索开放平台:RAG智能化工作流助力 AI 搜索

——已获知乎作者【小小将】授权转载 最近AI圈的变化可谓是日新月异&#xff0c;随着大模型的技术突飞猛进&#xff0c;大模型的能力日益增强。这些都驱动着我们的搜索技术快速演进到了下一代&#xff0c;也就是 AI 搜索的技术。大模型的快速发展不仅重塑了搜索技术的基础&…...

同z科技面经

同z科技-2025-4-23 1.自我介绍 个人信息 校园经历 实习经历 项目经历 个人技能掌握 目前学习技术 2.封装缓存工具类怎么封装的 先介绍使用缓存的问题 解决的逻辑 封装的逻辑 应用 缓存穿透&#xff1a; 缓存雪崩&#xff1a; 缓存击穿&#xff1a; https://www…...

制作一款打飞机游戏19:碰撞检测

在这一章中&#xff0c;我们致力于解决碰撞检测问题&#xff0c;但它并不如我们所愿工作。 碰撞检测问题 今天我想解决的是碰撞检测问题&#xff0c;这个令人畏惧的碰撞检测。我理解&#xff0c;这里有很多复杂的if语句&#xff0c;但我们可以做到。 不过&#xff0c;在此之…...

python后端程序部署到服务器 Ubuntu并配合 Vue 前端页面运行

将 PyCharm 研发的 Web 后端系统程序部署到 Ubuntu 24.04 服务器并配合 Vue 前端页面运行&#xff0c;可按以下步骤操作&#xff1a; 1. 服务器环境准备 在开始部署之前&#xff0c;需要在 Ubuntu 24.04 服务器上安装必要的软件。 # 更新系统软件包 sudo apt update sudo ap…...

9N60-ASEMI无人机专用功率器件9N60

编辑&#xff1a;LL 9N60-ASEMI无人机专用功率器件9N60 型号&#xff1a;9N60 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大漏源电流&#xff1a;9A 漏源击穿电压&#xff1a;600V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;1.00Ω …...

Java单例模式详解:实现线程安全的全局访问点

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、什么是单例模式&#xff1f; 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它保证一个类仅有一个实例&#xff…...

【无人机】无人机光流模块Optical Flow设置(三),光流测距一体传感器的配置。凌启科技的光流测距一体模块的测试。

目录 1、光流测距一体模块的配置&#xff0c;详细步骤 1.1、连接 1.2、上位机使用 1.3、切换为PX4协议 2、适配PX4飞控&#xff0c;QGC上参数配置 2.0、安装连接 2.1、串口配置&#xff1a; 2.2、启用光流辅助功能 2.3、启用测距辅助功能 2.4、高度参考设置 2.5、重…...

电路中的DGND、GROUND、GROUND_REF的区别,VREF、VCC、VDD、VEE和VSS的区别?

目录 1 DGND、GROUND、GROUND_REF的区别 1.1 DGND&#xff08;Digital Ground&#xff09; 1.2 GROUND&#xff08;Ground&#xff09; 1.3 GROUND_REF&#xff08;Ground Reference&#xff09; 1.4 区别 2 VREF、VCC、VDD、VEE和VSS的区别 2.1 VREF&#xff08;Refere…...

VSFTPD+虚拟用户+SSL/TLS部署安装全过程(踩坑全通)

Author : Spinach | GHB Link : http://blog.csdn.net/bocai8058文章目录 前言准备配置虚拟用户1.创建虚拟用户列表文件2.生成数据库文件3.设置虚拟用户独立访问权限 配置PAM认证1.创建PAM配置文件2.测试PAM认证 创建虚拟用户映射的系统用户生成SSL/TLS证书配置VSFTPD服务1…...

Java-File类详解(一篇讲透)

一&#xff1a;File类的实例化及常用方法 1.1 定义 1.2 构造器 &#xff08;1&#xff09;File(String pathname) 文件的路径表示方式 测试&#xff1a; &#xff08;2&#xff09;File(String parent,String child) 在父路径下创建子文件&#xff08;没后缀是目录&#xff0c…...

Representation Flow for Action Recognition论文笔记

原文笔记&#xff1a; What&#xff1a; 在本文中&#xff0c;我们提出了一种受光流算法启发的CNN层&#xff0c;用于学习动作识别的运动表示&#xff0c;而无需计算光流。我们的表示流层是一个完全可微分的层&#xff0c;旨在捕获模型中任何表示通道的“流”。其迭代流量优化…...

云计算领域需掌握的核心技术

云计算作为现代信息技术的核心基础设施&#xff0c;涵盖从基础资源管理到上层应用开发的完整技术栈。它依靠强大的计算能力&#xff0c;使得成千上万的终端用户不担心所使用的计算技术和接入的方式等都能够进行有效的依靠网络连接起来的硬件平台的计算能力来实施多种应用。 一、…...

Android仿今日头条Kotlin版本

软件信息 gradle-8.0Sdk信息 //编译版本 compileSdk33 //最小版本 minSdk24 //目标版本 targetSdk31Android Studio Giraffe | 2022.3.1 Patch 2&#xff08;建议版本不要太低&#xff09;MVVMAndroid Jetpack 项目注意 没有服务器&#xff0c;用的是Apifox模拟服务器返回&a…...

Javashop新零售电商系统:构建智能零售生态的终极解决方案

JavaShop Javashop新零售电商系统&#xff1a;构建智能零售生态的终极解决方案引言&#xff1a;数字化转型浪潮中的零售业变革Javashop新零售系统核心优势1. 全渠道融合&#xff1a;打破线上线下壁垒2. 智能化门店管理&#xff1a;赋能传统零售3. 智慧营销与会员运营 系统功能模…...

vscode如何多行同时编辑,vscode快速选中多行快捷键

目录 vscode如何多行同时编辑&#xff0c;vscode快速选中多行快捷键 一、实践情景 二、不同多选情景的操作方案 1、使用 Alt 鼠标点击选择任意行的任意位置 2、使用快捷键 Shift Alt 鼠标拖动 3、使用快捷键添加多行光标 4、结合正则表达式批量编辑 5、使用扩展插件&…...

珈和科技助力“农险提效200%”!“遥感+”技术创新融合省级示范项目荣登《湖北卫视》!

近日&#xff0c;湖北卫视《湖北十分》栏目报道了珈和科技遥感赋能农业保险创新&#xff0c;典型项目入选十大省级卫星应用示范标杆事迹&#xff0c;系统展示了珈和科技在卫星遥感与农业保险融合领域的创新成果。 作为空天农业领域的领军企业&#xff0c;珈和科技依托创新构建…...

UIAutomator 与 Playwright 在 AI 自动化中的界面修改对比

UIAutomator 与 Playwright 在 AI 自动化中的界面修改对比 在 AI 驱动的 UI 自动化中,Playwright(主要用于 Web)和 UIAutomator(用于 Android)的设计定位不同,对界面修改的支持也截然不同。下面从界面修改能力、API 设计、替代方案和实践建议等方面进行分析,对比两者在…...

Redisson Watchdog实现原理与源码解析:分布式锁的自动续期机制

引言 在分布式系统中&#xff0c;Redis分布式锁是解决资源竞争问题的常用方案。然而&#xff0c;当持有锁的客户端因GC、网络延迟或处理时间过长导致锁过期时&#xff0c;可能引发数据一致性问题。Redisson的Watchdog&#xff08;看门狗&#xff09;机制通过自动续期解决了这一…...

在C#串口通信中,一发一收的场景,如何处理不同功能码的帧数据比较合理,代码结构好

在 C# 串口通信的一发一收场景里&#xff0c;处理不同功能码的帧数据可采用以下合理的代码结构&#xff0c;它能让代码更具可读性、可维护性和可扩展性。 实现思路 定义帧结构&#xff1a;创建一个类来表示通信帧&#xff0c;其中包含功能码、数据等信息。功能码处理逻辑&…...

easypoi 实现word模板导出

特此非常致谢&#xff1a;easypoi实现word模板 基础的可以参考上文&#xff1b; 但是我的需求有一点点不一样。 这是我的模板&#xff1a;就是我的t.imgs 是个list 但是很难过的是easy poi 我弄了一天&#xff0c;我都没有弄出来嵌套list循环怎么输出显示&#xff0c;更难过…...

集结号海螺捕鱼服务器调度与房间分配机制详解:六

本篇围绕服务器调度核心逻辑进行剖析&#xff0c;重点讲解用户连接过程、房间分配机制、服务端并发策略及常见性能瓶颈优化。适用于具备中高级 C 后端开发经验的读者&#xff0c;覆盖网络会话池、逻辑服调度器与房间生命周期管理等关键模块。 一、服务器结构概览 整体系统采用…...

opencv--图像滤波

图像滤波 含义 方法 噪声是怎么产生的 线性滤波 概念 利用窗口对图像中的像素进行加权求和的滤波方式。 图像来源于小虎教程。 图像的滤波是二维滤波的过程。 滤波器窗口&#xff1a; 滤波器窗口&#xff08;也称为卷积核或模板&#xff09;是一个小的矩阵&#xff08;通常为…...

uniapp返回上一页接口数据更新了,页面未更新

注意&#xff1a;不是组件套组件可以不使用setTimeout延时 返回上一页一般会走onshow&#xff0c;但是接口更新了页面未更新 onShow(() > {// 切换城市后重新调用数据if (areaId.value) {const timer setTimeout(async () > {timer && clearTimeout(timer);…...