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

FairyGUI-Unity侧菜单扩展

目录

缘由:

分析: 

准备:

完整代码:

缘由:

在使用FairyGUI作为项目UI开发时,有时会使用FairyGUI提供的Scripting Define Symbols。当前FairyGUI中的Scripting Define Symbols有:

骨骼动画 Spine:FAIRYGUI_SPINE,龙骨:FAIRYGUI_DRAGONBONES

字体 TextMeshPro:FAIRYGUI_TMPRO

使用ToLua:FAIRYGUI_TOLUA

使用Puerts:FAIRYGUI_PUERTS

显示阿拉伯文本:RTL_TEXT_SUPPORT

UI自动化测试:FAIRYGUI_TEST

 为了方便开发,以上Scripting Define Symbols我将其做成了Unity的菜单,直接看完整代码。

分析: 

在开始制作菜单之前,需要做一些准备工作。比如上述的Scripting Define Symbols是否需要额外的Unity资源包,是否需要熟悉Unity编辑器中的一些方法才能进行?

而且需要注意的是新建的Unity工程中,TextMeshPro组件的必要资源库是需要手动导入或引用的,所以在使用FGUI提供的FAIRYGUI_TMPRO时,需要对TextMeshPro包进行检测。

对于编辑器中的Scripting Define Symbols设置可以通过方法GetScriptingDefineSymbolsForGrouphSetScriptingDefineSymbolsForGroup进行操作。菜单状态则可以通过方法:GetCheckedSetChecked来进行操作。菜单状态的变化Scripting Define Symbols设置有关,所以还要自定义一个同步刷新菜单状态的方法RefreshMenuState

准备:

分析结束,我们在代码中写一下上面的分析结果。新建脚本EditorMenuTool,空间名设置为FairyGUIEditor,添加对UnityEditor的引用。将新建的EditorMenuTool脚本,放到FairyGUI的Editor目录下(也可以根据项目目录结构放置),打开脚本。

#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;namespace FairyGUIEditor
{public class EditorMenuTool{}
}
#endif

Scripting Define Symbols的操作方法:

        /// <summary>/// 获取Scripting Define Symbols的值/// </summary>/// <returns></returns>private static string GetScriptingDefineSymbolsForGroup(){return PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);}/// <summary>/// 设置Scripting Define Symbols的值/// </summary>/// <param name="newSymbol">新的宏定义</param>private static void SetScriptingDefineSymbolsForGroup(string newSymbol){PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,newSymbol);}/// <summary>/// 检测Scripting Define Symbols中是否存在目标值/// </summary>/// <param name="define">目标宏</param>/// <returns></returns>private static bool CheckScriptingDefineSymbolsExist(string define){string symbol = GetScriptingDefineSymbolsForGroup();return symbol.Contains(define);}/// <summary>/// 根据菜单状态修改目标宏/// </summary>/// <param name="define">目标宏定义</param>/// <param name="menuState">当前菜单状态</param>private static void SwitchToTargetState(string define, bool menuState = false){//检测目标宏定义if (define == null)return;//获取当前的宏定义string symbol = GetScriptingDefineSymbolsForGroup();if (menuState) //菜单已选中{//获取目标宏所在的位置int index = symbol.IndexOf(define);if (index < 0)return;//如果不在第一个 则将其前面的分号删掉if (index > 0)index -= 1;int length = define.Length;//如果当前宏长度大于要删除的当前长度,才会有分号if (symbol.Length > length)length += 1;//删除目标宏定义symbol = symbol.Remove(index, length);SetScriptingDefineSymbolsForGroup(symbol);}else //菜单未选中{//如果当前的宏是空的,则直接将目标的宏加入if (symbol.Equals(string.Empty))SetScriptingDefineSymbolsForGroup(define);else{//否则,以分号分割加入目标宏string newSymbol = symbol + ";" + define;SetScriptingDefineSymbolsForGroup(newSymbol);}}}

包管理(PackageManager)的检测方法:

        /// <summary>/// 检测目标包是否存在/// </summary>/// <param name="packageName">包名</param>/// <param name="callback"></param>private static void CheckTargetPackageExists(string packageName,Action<bool> callback = null){// 创建一个ListRequest请求,用来查询PackageManager中已经安装的packages列表ListRequest request = Client.List();// 发送ListRequest请求,并在每一帧检查请求是否已经完成EditorApplication.CallbackFunction checkUpdateAction = null;checkUpdateAction = () =>{if (request.IsCompleted){bool packageExists = false;EditorUtility.ClearProgressBar();if (request.Status == StatusCode.Success){// 遍历packages列表,查找目标packageName是否存在foreach (var package in request.Result){if (package.name.Contains(packageName) || package.displayName.Contains(packageName)){packageExists = true;break;}}}else if (request.Status >= StatusCode.Failure){Debug.LogError(request.Error.message);}callback?.Invoke(packageExists);// 取消update回调函数EditorApplication.update -= checkUpdateAction;}};EditorApplication.update += checkUpdateAction;EditorUtility.DisplayProgressBar("Check", "Please wait...", 0f);}

同步刷新菜单的方法:

/// <summary>
/// 刷新菜单状态
/// 标签"UnityEditor.Callbacks.DidReloadScripts"可以在脚本编译完成后自动回调这个方法
/// 标签"RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)"在场景加载前执行这个方法
/// </summary>
[UnityEditor.Callbacks.DidReloadScripts,RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void RefreshMenuState()
{//添加需要更新菜单
}

添加UnityEditor.Callbacks.DidReloadScriptsRuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)标签,会在脚本编译完或场景加载前进行状态同步,是个很方便的功能。举例:和小伙伴们一起开发时,只需要自己这边配置好,同步到其他小伙伴那边时,他们的编译器自动就会刷新新配置对应菜单状态。 

完整代码:

#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.UI;
using UnityEditor.PackageManager.Requests;namespace FairyGUIEditor
{public class EditorMenuTool{#region Define Symbols/// <summary>/// <a href="https://www.fairygui.com/docs/editor/skeleton#%E5%9C%A8unity%E4%B8%AD%E4%BD%BF%E7%94%A8"> 骨骼动画 </a> Spine:FAIRYGUI_SPINE,龙骨:FAIRYGUI_DRAGONBONES/// </summary>private const string DefineSpine = "FAIRYGUI_SPINE", DefineDragonBones = "FAIRYGUI_DRAGONBONES";/// <summary>/// <a href="https://www.fairygui.com/docs/editor/font#textmeshpro%E6%94%AF%E6%8C%81"> 字体 TextMeshPro </a>:FAIRYGUI_TMPRO/// </summary>private const string DefineTMP = "FAIRYGUI_TMPRO";/// <summary>/// <a href="https://www.fairygui.com/docs/unity/lua"> 使用ToLua </a>:FAIRYGUI_TOLUA/// </summary>private const string DefineToLua = "FAIRYGUI_TOLUA";/// <summary>/// <a href="https://www.fairygui.com/docs/unity/puerts"> 使用Puerts </a>:FAIRYGUI_PUERTS/// </summary>private const string DefinePuerts = "FAIRYGUI_PUERTS";/// <summary>/// <a href="https://www.fairygui.com/docs/unity/special#%E9%98%BF%E6%8B%89%E4%BC%AF%E8%AF%AD%E8%A8%80%E6%96%87%E5%AD%97%E6%98%BE%E7%A4%BA"> 阿拉伯语言文字显示 </a>:RTL_TEXT_SUPPORT/// </summary>private const string DefineRTL = "RTL_TEXT_SUPPORT";/// <summary>/// <a href="https://www.fairygui.com/docs/unity/special#ui%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95"> UI自动化测试 </a>:FAIRYGUI_TEST/// </summary>private const string DefineAirTest = "FAIRYGUI_TEST";#endregionprivate const string PackageName = "TextMeshPro";private const string TextMeshProCheckPkg = "FairyGUI/TextMeshPro/Check Package";private const string TextMeshProEssential = "FairyGUI/TextMeshPro/Import TMP Essential Resources";private const string MenuNameTextMeshPro = "FairyGUI/TextMeshPro/Use TextMeshPro";private const string MenuNameSpine = "FairyGUI/Use Spine";private const string MenuNameDragonBones = "FairyGUI/Use DragonBones";private const string MenuNameToLua = "FairyGUI/Use ToLua";private const string MenuNamePuerts = "FairyGUI/Use Puerts";private const string MenuNameRTLTextSupport = "FairyGUI/Use RTLTextSupport";private const string MenuNameAirTest = "FairyGUI/Use AirTest";/// <summary>/// 检测TextMeshPro包是否存在/// </summary>[MenuItem(TextMeshProCheckPkg,false,1000)]private static void CheckTextMeshProPackage(){CheckTargetPackageExists(PackageName, b =>{//不存在则打开包管理面板,并搜索if (!b){//UnityEditor.PackageManager.UIWindow.Open(PackageName);}else{//提示已经安装了EditorUtility.DisplayDialog("Tips", $"{PackageName} package is installed!\n{PackageName}包已存在!","Ok");}});}/// <summary>/// 导入TextMeshPro包必备资源/// </summary>[MenuItem(TextMeshProEssential,false,1015)]private static void ImportTMPEssentialResources(){//做一次安全检查if (UnityEditor.PackageManager.PackageInfo.FindForAssetPath("Packages/com.unity.textmeshpro/Scripts/Runtime/TextMeshPro.cs") == null) {Debug.LogError("TextMeshPro package is not installed.");return;}//执行目标菜单项EditorApplication.ExecuteMenuItem("Window/TextMeshPro/Import TMP Essential Resources");}/// <summary>/// 启用或关闭TextMeshPro支持/// </summary>[MenuItem(MenuNameTextMeshPro,false,1030)]private static void SelectTextMeshPro(){//获取当前状态bool state = Menu.GetChecked(MenuNameTextMeshPro);//切换宏定义状态SwitchToTargetState(DefineTMP,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭Spine/// </summary>[MenuItem(MenuNameSpine,false,1015)]private static void SelectSpine(){//获取当前状态bool state = Menu.GetChecked(MenuNameSpine);//切换宏定义状态SwitchToTargetState(DefineSpine,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭DragonBones/// </summary>[MenuItem(MenuNameDragonBones,false,1030)]private static void SelectDragonBones(){//获取当前状态bool state = Menu.GetChecked(MenuNameDragonBones);//切换宏定义状态SwitchToTargetState(DefineDragonBones,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭ToLua/// </summary>[MenuItem(MenuNameToLua,false,1045)]private static void SelectToLua(){//获取当前状态bool state = Menu.GetChecked(MenuNameToLua);//切换宏定义状态SwitchToTargetState(DefineToLua,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭Puerts/// </summary>[MenuItem(MenuNamePuerts,false,1060)]private static void SelectPuerts(){//获取当前状态bool state = Menu.GetChecked(MenuNamePuerts);//切换宏定义状态SwitchToTargetState(DefinePuerts,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭阿拉伯语言文字/// </summary>[MenuItem(MenuNameRTLTextSupport,false,1075)]private static void SelectRTLTextSupport(){//获取当前状态bool state = Menu.GetChecked(MenuNameRTLTextSupport);//切换宏定义状态SwitchToTargetState(DefineRTL,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 启用或关闭UI自动化测试/// </summary>[MenuItem(MenuNameAirTest,false,1090)]private static void SelectUIAirTest(){//获取当前状态bool state = Menu.GetChecked(MenuNameAirTest);//切换宏定义状态SwitchToTargetState(DefineAirTest,state);//刷新菜单状态RefreshMenuState();//更新AssetDatabase.Refresh();}/// <summary>/// 刷新菜单状态/// 标签"UnityEditor.Callbacks.DidReloadScripts"可以在脚本编译完成后自动回调这个方法/// 标签"RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)"在场景加载前执行这个方法/// </summary>[UnityEditor.Callbacks.DidReloadScripts,RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]private static void RefreshMenuState(){//放置需要更新菜单Menu.SetChecked(MenuNameTextMeshPro, CheckScriptingDefineSymbolsExist(DefineTMP));Menu.SetChecked(MenuNameSpine, CheckScriptingDefineSymbolsExist(DefineSpine));Menu.SetChecked(MenuNameDragonBones, CheckScriptingDefineSymbolsExist(DefineDragonBones));Menu.SetChecked(MenuNameToLua, CheckScriptingDefineSymbolsExist(DefineToLua));Menu.SetChecked(MenuNamePuerts, CheckScriptingDefineSymbolsExist(DefinePuerts));Menu.SetChecked(MenuNameRTLTextSupport, CheckScriptingDefineSymbolsExist(DefineRTL));Menu.SetChecked(MenuNameAirTest, CheckScriptingDefineSymbolsExist(DefineAirTest));}#region Package Check/// <summary>/// 检测目标包是否存在/// </summary>/// <param name="packageName">包名</param>/// <param name="callback"></param>private static void CheckTargetPackageExists(string packageName,Action<bool> callback = null){// 创建一个ListRequest请求,用来查询PackageManager中已经安装的packages列表ListRequest request = Client.List();// 发送ListRequest请求,并在每一帧检查请求是否已经完成EditorApplication.CallbackFunction checkUpdateAction = null;checkUpdateAction = () =>{if (request.IsCompleted){bool packageExists = false;EditorUtility.ClearProgressBar();if (request.Status == StatusCode.Success){// 遍历packages列表,查找目标packageName是否存在foreach (var package in request.Result){if (package.name.Contains(packageName) || package.displayName.Contains(packageName)){packageExists = true;break;}}}else if (request.Status >= StatusCode.Failure){Debug.LogError(request.Error.message);}callback?.Invoke(packageExists);// 取消update回调函数EditorApplication.update -= checkUpdateAction;}};EditorApplication.update += checkUpdateAction;EditorUtility.DisplayProgressBar("Check", "Please wait...", 0f);}#endregion#region Scripting Define Symbols/// <summary>/// 获取Scripting Define Symbols的值/// </summary>/// <returns></returns>private static string GetScriptingDefineSymbolsForGroup(){return PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);}/// <summary>/// 设置Scripting Define Symbols的值/// </summary>/// <param name="newSymbol">新的宏定义</param>private static void SetScriptingDefineSymbolsForGroup(string newSymbol){PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,newSymbol);}/// <summary>/// 检测Scripting Define Symbols中是否存在目标值/// </summary>/// <param name="define">目标宏</param>/// <returns></returns>private static bool CheckScriptingDefineSymbolsExist(string define){string symbol = GetScriptingDefineSymbolsForGroup();return symbol.Contains(define);}/// <summary>/// 更新菜单状态修改目标宏/// </summary>/// <param name="define">目标宏定义</param>/// <param name="menuState">当前菜单状态</param>private static void SwitchToTargetState(string define, bool menuState = false){//检测目标宏定义if (define == null)return;//获取当前的宏定义string symbol = GetScriptingDefineSymbolsForGroup();if (menuState) //菜单已选中{//获取目标宏所在的位置int index = symbol.IndexOf(define);if (index < 0)return;//如果不在第一个 则将其前面的分号删掉if (index > 0)index -= 1;int length = define.Length;//如果当前宏长度大于要删除的当前长度,才会有分号if (symbol.Length > length)length += 1;//删除目标宏定义symbol = symbol.Remove(index, length);SetScriptingDefineSymbolsForGroup(symbol);}else //菜单未选中{//如果当前的宏是空的,则直接将目标的宏加入if (symbol.Equals(string.Empty))SetScriptingDefineSymbolsForGroup(define);else{//否则,以分号分割加入目标宏string newSymbol = symbol + ";" + define;SetScriptingDefineSymbolsForGroup(newSymbol);}}}#endregion}
}#endif

相关文章:

FairyGUI-Unity侧菜单扩展

目录 缘由&#xff1a; 分析&#xff1a; 准备&#xff1a; 完整代码&#xff1a; 缘由&#xff1a; 在使用FairyGUI作为项目UI开发时&#xff0c;有时会使用FairyGUI提供的Scripting Define Symbols。当前FairyGUI中的Scripting Define Symbols有&#xff1a; 骨骼动画 …...

学习笔记十八:污点、容忍度

污点、容忍度 污点、容忍度管理节点污点把k8snode2当成是生产环境专用的&#xff0c;其他node是测试的给k8snode1也打上污点 污点、容忍度 给了节点选则的主动权&#xff0c;我们给节点打一个污点&#xff0c;不容忍的pod就运行不上来&#xff0c;污点就是定义在节点上的键值属…...

amis百度前端框架,在js中使用amis写json转页面

amis百度前端框架,在js中使用用amis写的json页面 1.在项目中使用百度 amis 的sdk做开发库。 <script src="./sdk/sdk/sdk.js"></script> 2。加载sdk中的库: amis = amisRequire(amis/embed);amisLib = amisRequire(amis);const match = amisRequire…...

openEuler安装jdk、openEuler离线安装jdk、openEuler设置jdk、openEuler在线安装

记录一下本人使用openEuler安装jdk的过程,希望能帮到看到帖子的你! 方式一:在线安装: 在 openEuler 上安装 JDK(Java Development Kit)的步骤如下: 更新系统: 在安装 JDK 之前,建议先更新系统软件包。打开终端并执行以下命令: sudo dnf update 这将更新系统中的软…...

Photoshop制作漂亮光泽感3D按钮

原文链接(https://img-blog.csdnimg.cn/45472c07f29944458570b59fe1f9a0e0.png)...

【网络爬虫】模拟登录与代理

代理...

无线局域网基础知识与架构

1.1 无线局域网 无线局域网(Wireless Local Area Network&#xff0c;WLAN)是指以无线信道作为传输 媒介的计算机局域网络&#xff0c;是计算机网络与无线通信技术相结合的产物&#xff0c;它以无线多 址信道作为传输媒介&#xff0c;提供传统有线局域网的功能&#xff0c;能…...

uniapp tabbar 浏览器调试显示 真机不显示

解决方案&#xff0c;把tabBar里面的单位全改为px&#xff0c;rpx是不会显示的&#xff01; 注意了&#xff0c;改完一定要重新运行&#xff0c;不然无效&#xff0c;坑爹 "tabBar": {"borderStyle": "black","selectedColor": &quo…...

极智AI | 地平线BPU跑通YOLOv5

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文来介绍一下 地平线BPU跑通YOLOv5。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq 硬件设备为地平线旭日x3,开发环境和执行环…...

循环服务器(同时连接多个客户端,为每个客户端创建一个子进程处理其消息)

服务器 客户端 结果...

【从零学习python 】38.Python包的使用及导入方式

文章目录 包的使用1. 导入包的方式总结2. __init__.py文件有什么用3. __all__ 注意事项进阶案例 包的使用 一个模块就是一个 py 文件&#xff0c;在 Python 里为了对模块分类管理&#xff0c;就需要划分不同的文件夹。多个有联系的模块可以将其放到同一个文件夹下&#xff0c;为…...

docker 容器满了常用处理方法

docker 容器满了常用处理方法 1、运行 df -h 查看剩余磁盘占用情况 2、进入到docker目录 cd /var/lib/docker 3、运行du -h --max-depth1 &#xff08;检索文件的最大深度1&#xff0c;即只检索汇总计算当前目录下的文件&#xff09; 4、进入占用最大的 /containers文件夹&am…...

28、springboot的静态模版(前端页面)重加载和 devtools开发者工具

springboot的静态模版重加载和 devtools开发者工具 总结&#xff1a;实现静态模板重加载的两个方法 方法1&#xff1a;在 yml 配置文件&#xff0c;关闭页面模板缓存&#xff0c; 再按 ctrlf9 重新构建 方法2&#xff1a;直接添加 devtools 依赖&#xff0c;再按 ctrlf9 重新构…...

[FPGA IP系列] FPGA常用存储资源大全(RAM、ROM、CAM、SRAM、DRAM、FLASH)

本文主要介绍FPGA中常用的RAM、ROM、CAM、SRAM、DRAM、FLASH等资源。 一、RAM RAM(Random Access Memory)是FPGA中最基本和常用的内部存储块&#xff0c;根据不同架构可以实现不同容量&#xff0c;最大可达几十Mb。 FPGA中的RAM主要包括: 分布式RAM&#xff1a;存在于逻辑块…...

Spark SQL优化:NOT IN子查询优化解决

背景 有如下的数据查询场景。 SELECT a,b,c,d,e,f FROM xxx.BBBB WHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} AND predict_type not IN ( SELECT distinct a FROM xxx.AAAAAWHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} ) 分析 通过查看SQL语句的执行计划基本…...

代码审计-java项目-组件漏洞审计

代码审计必备知识点&#xff1a; 1、代码审计开始前准备&#xff1a; 环境搭建使用&#xff0c;工具插件安装使用&#xff0c;掌握各种漏洞原理及利用,代码开发类知识点。 2、代码审计前信息收集&#xff1a; 审计目标的程序名&#xff0c;版本&#xff0c;当前环境(系统,中间件…...

接口测试的测试用例该怎么写呢

接口测试是软件测试中非常重要的一部分&#xff0c;因为接口的稳定性和可靠性对于整个系统的质量和用户体验都有很大的影响。在接口测试中&#xff0c;编写有效的测试用例是非常关键的一步。本文将介绍如何编写接口测试的测试用例&#xff0c;包括测试用例的设计和编写方法&…...

C语言例题讲解(if语句,循环语句,函数)

目录 if语句例题题目分析代码题目总结 循环语句例题题目分析代码题目总结 函数例题题目分析代码题目总结 if语句例题 计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值&#xff0c;打印出结果题目分析 1&#xff1a;首先我们不难看出算式中的加号和减号是交替出现的&#xff0…...

深入探索JavaEE单体架构、微服务架构与云原生架构

课程链接&#xff1a; 链接: https://pan.baidu.com/s/1xSI1ofwYXfqOchfwszCZnA?pwd4s99 提取码: 4s99 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v4的分享 课程介绍&#xff1a; &#x1f50d;【00】模块零&#xff1a;开营直播&a…...

【STM32】FreeRTOS互斥量学习

互斥量&#xff08;Mutex&#xff09; 互斥量又称互斥信号量&#xff08;本质也是一种信号量&#xff0c;不具备传递数据功能&#xff09;&#xff0c;是一种特殊的二值信号量&#xff0c;它和信号量不同的是&#xff0c;它支持互斥量所有权、递归访问以及防止优先级翻转的特性…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...