Unity组件开发--AB包打包工具
1.项目工程路径下创建文件夹:ABundles


2.AB包打包脚本:
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;public class AssetBundlePackage {static string[] GetBuildScenes() {List<string> sceneArray = new List<string>();foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes) {if (e == null) continue;if (e.enabled) sceneArray.Add(e.path);}return sceneArray.ToArray();}[MenuItem("BuildScene/Build")]public static void BuildScene() {//BundleAssetsBundle_Webgl();string folderPath = EditorUtility.OpenFolderPanel("Select Folder", "", "");Debug.Log("Selected Folder: " + folderPath);BuildPipeline.BuildPlayer(new string[] { "Assets/GameStart.unity" }, folderPath, BuildTarget.WebGL, BuildOptions.AutoRunPlayer);}[MenuItem("BuildScene/BuildForMobile")]public static void BuildSceneForMobile(){//BundleAssetsBundle_Webgl();string folderPath = EditorUtility.OpenFolderPanel("Select Folder", "", "");Debug.Log("Selected Folder: " + folderPath);BuildPipeline.BuildPlayer(new string[] { "Assets/GameStartMoibile.unity" }, folderPath, BuildTarget.WebGL, BuildOptions.AutoRunPlayer);}[MenuItem("SceneAsset/BuildCurrent")]public static void BuildCurrentScene() {string rootPath = Application.dataPath.ToLower().Replace("assets", "") + "ABundles/webgl/scenes";string scenePath = EditorSceneManager.GetActiveScene().path;string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath).ToLower();AssetBundleBuild assetBundleBuild = new AssetBundleBuild();assetBundleBuild.assetNames = new []{ scenePath };assetBundleBuild.assetBundleName = sceneName + ".bundle";BuildPipeline.BuildAssetBundles(rootPath, new AssetBundleBuild[] { assetBundleBuild}, BuildAssetBundleOptions.None, BuildTarget.WebGL);}[MenuItem("SceneAsset/BuildAllScene")]public static void BuildAllScene() {bool isOk = EditorUtility.DisplayDialog("确认框", "是否将所有场景打成AB包", "确认", "取消");if (!isOk) {return;}//AB包路径是ABundlesstring rootPath = Application.dataPath.ToLower().Replace("assets","") + "ABundles/webgl/scenes";var allScenesPath = GetBuildScenes();foreach (var scenePath in allScenesPath) {string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath).ToLower();AssetBundleBuild assetBundleBuild = new AssetBundleBuild();assetBundleBuild.assetNames = new[] { scenePath };assetBundleBuild.assetBundleName = sceneName + ".bundle";Debug.Log(sceneName + scenePath);BuildPipeline.BuildAssetBundles(rootPath, new AssetBundleBuild[] { assetBundleBuild }, BuildAssetBundleOptions.None, BuildTarget.WebGL);}}[MenuItem("AssetBundle/BuildWebGL")]public static void BundleAssetsBundle_Webgl() {Debug.Log("BundleAssetsBundle WebGL");BuildAllAssetBundles();}private static void BuildAssetsBundle(BuildTarget target) {//string packagePath = Application.streamingAssetsPath;//if (packagePath.Length <= 0 && !Directory.Exists(packagePath))//{// return;//}//BuildPipeline.BuildAssetBundles(packagePath, BuildAssetBundleOptions.UncompressedAssetBundle, target);}//Asset/BundleAsset/Prefab/Com/a.bundle Prefab/Com/apublic static string RemovePrefix(string inputString) {inputString = inputString.Replace("\\", "/");string prefix = "Assets/BundleAsset/";string result = inputString.Replace(prefix, "");return result.Replace(".bundle", "");}static void BuildAllAssetBundles() {string prefabsFolderPath = "Assets/BundleAsset/Prefab";if (!Directory.Exists(prefabsFolderPath)) {Debug.LogError($"Folder {prefabsFolderPath} does not exist!");return;}//AB包路径是ABundlesstring rootPath = Application.dataPath.ToLower().Replace("assets", "") + "ABundles/webgl";if (!Directory.Exists(rootPath)) {Debug.LogError($"Folder {rootPath} does not exist!");return;}string[] prefabGUIDs = AssetDatabase.FindAssets("t:Prefab", new[] { prefabsFolderPath });foreach (var prefabGUID in prefabGUIDs) {string prefabPath = AssetDatabase.GUIDToAssetPath(prefabGUID);GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);if (prefab == null) {continue;}var assetPath = AssetDatabase.GetAssetPath(prefab);var dependencies = GetAllDependencies(assetPath).ToArray();var withoutEx = Path.GetFileNameWithoutExtension(prefabPath);AssetBundleBuild assetBundleBuild = new AssetBundleBuild();assetBundleBuild.assetBundleName = RemovePrefix(withoutEx).ToLower() + ".bundle";assetBundleBuild.assetNames = dependencies;var directName = Path.GetDirectoryName(assetPath);var outPackagePath = $"{rootPath}/{RemovePrefix(directName).ToLower()}";Debug.Log($"prefabPath {prefabPath}");if (!Directory.Exists(outPackagePath)) {Directory.CreateDirectory(outPackagePath);}BuildPipeline.BuildAssetBundles(outPackagePath, new AssetBundleBuild[] { assetBundleBuild }, BuildAssetBundleOptions.None, BuildTarget.WebGL);}Debug.Log("BuildAssetBundles ok");}public static List<string> GetAllDependencies(string assetPath) {var list = new List<string>();var dependencies = AssetDatabase.GetDependencies(assetPath, false);foreach (var dependency in dependencies) {if (Path.GetExtension(dependency) == ".cs" || Path.GetExtension(dependency) == ".meta" || Path.GetExtension(dependency) == ".DS_Store") {continue;}list.Add(dependency);}list.Add(assetPath);return list;}}
3.需要打包的场景添加到打包配置:
4.unity编辑器生成菜单:

5.场景加载AB包管理器:
using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.IO;
using UnityEngine.Networking;
using GLTFast;
using LitJson;
using System.Web;public class SceneLoader : MonoBehaviour {public int TemplateId;public bool useBundle;public bool isDeBug;public bool isShowCase;public bool isMobileTest;[Header("天空盒材质球")]public UnityEngine.Material skyboxMaterial;bool sceneIsLoaded = false;[DllImport("__Internal")]private static extern string GetUA();public virtual void Awake() {#if !UNITY_EDITOR && UNITY_WEBGLstring a = GetUA();if (a == "1"){//PC端Debug.Log("当前运行环境在PC端");PlayerData.Instance.isRunningPC = true;}if (a == "2"){//移动端Debug.Log("当前运行环境在移动端");PlayerData.Instance.isRunningPC = false;}
#endif#if UNITY_EDITORAppConst.UseAssetBundle = useBundle;#endifAppConst.useShowBundlePath = isShowCase;DontDestroyOnLoad(gameObject);EventManager.Instance.AddListener(EventName.LoadSceneAction, OnSceneLoad);EventManager.Instance.AddListener(EventName.OnSceneCfgLoadEnd, RemoveUnuse);}public virtual void Start() {var fps = transform.Find("FPS");if (fps) {fps.gameObject.SetActive(isDeBug);}if (isMobileTest) LoadNetCofig();}void LoadNetCofig() {var configPath = Application.dataPath;#if UNITY_EDITORvar filepath = Path.Combine(Application.dataPath.Replace("Assets", ""), "config.txt");
#elsevar filepath = Path.Combine(Application.dataPath, "config.txt");
#endifDebug.Log("configPath" + filepath);filepath = filepath.Replace("\\", "/");StartCoroutine(LoadFileSetNetwork(filepath));}IEnumerator LoadFileSetNetwork(string filepath) {UnityWebRequest www = UnityWebRequest.Get(filepath);yield return www.SendWebRequest();if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError) {Debug.LogError(www.error);}else {string json = www.downloadHandler.text;var data = LitJson.JsonMapper.ToObject(json);if ((string)data["AssetBundleIP"] != string.Empty) {Host.AssetBundleIP = (string)data["AssetBundleIP"];}Host.gameServer = (string)data["local"];Host.ApiHost = (string)data["ApiHost"];Host.remote = (string)data["remote"];Debug.Log("url config:" + json);StartCoroutine(tempLoad());}}public IEnumerator tempLoad() {Debug.Log("OnBaelogin" + TemplateId);var SceneName = TemplateId.ToString();
#if UNITY_EDITORif (AppConst.UseAssetBundle) {yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);}else {yield return SceneManager.LoadSceneAsync(SceneName);}
#elseyield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
#endifEventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL); //这里有个坑, 如果把界面放在场景加载之前添加,会出现各种错误乱象UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);Debug.Log("DownLoadScenConfig");if (HttpHelper.Instance != null) {HttpHelper.Instance.GetDefaultSpaceImg();HttpHelper.Instance.DownLoadScenConfig();}}private void RemoveUnuse(object sender, EventArgs e) {RemoveSceneUnUseDefault();ResetSkyBox();}public void ResetSkyBox() {JsonData sceneJson = JsonMapper.ToObject(SceneModel.Instance.sceneJsonInitData);if (sceneJson["skyBox"] != null) {string imgdata = sceneJson["skyBox"]["body"].ToString();string decodedString = HttpUtility.UrlDecode(JsonMapper.ToObject(imgdata)["imgDatas"].ToString());StartCoroutine(LoadTexturesAndGenerateCubemap(JsonMapper.ToObject<List<skyImgData>>(decodedString)));}}private IEnumerator LoadTexturesAndGenerateCubemap(List<skyImgData> skyImgDataList) {Texture2D[] textures = new Texture2D[skyImgDataList.Count];Cubemap cubemap;for (int i = 0; i < skyImgDataList.Count; i++) {using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(skyImgDataList[i].url)) {yield return www.SendWebRequest();if (www.result == UnityWebRequest.Result.Success) {Texture2D texture = DownloadHandlerTexture.GetContent(www);textures[i] = texture;}else {Debug.LogError("Failed to load image: " + www.error);yield break;}}}Material material = new Material(skyboxMaterial);material.SetTexture("_FrontTex", textures[0]);material.SetTexture("_BackTex", textures[1]);material.SetTexture("_LeftTex", textures[2]);material.SetTexture("_RightTex", textures[3]);material.SetTexture("_UpTex", textures[4]);material.SetTexture("_DownTex", textures[5]);RenderSettings.skybox = material;}/// <summary>/// 移除场景默认设置的那些被删除的板/// </summary>public void RemoveSceneUnUseDefault() {var comVOs = SceneModel.Instance.rootCfg.comCfg.comVOs;var scene = SceneManager.GetActiveScene();GameObject[] roots = scene.GetRootGameObjects();foreach (GameObject root in roots) {var loaders = root.GetComponentsInChildren<ComLoader>();foreach (var loader in loaders) {if (comVOs.TryGetValue(loader.instanceName, out _) == false) {StartCoroutine(waitSeconds(loader.gameObject));}}}}IEnumerator waitSeconds(GameObject go) {yield return new WaitForEndOfFrame();GameObject.Destroy(go);}IEnumerator coLoadSceneAsync() {if (PlayerData.Instance.isRunningPC == false) {yield return new WaitForSeconds(1f);}#if UNITY_EDITORif (SceneModel.Instance.useGlb == false) {PlayerData.Instance.TemplateId = TemplateId;}
#endifvar SceneName = "";if (SceneModel.Instance.useGlb == true) {SceneName = "1000";}else {if (PlayerData.Instance.isRunningPC) {SceneName = PlayerData.Instance.TemplateId.ToString();}else {SceneName = PlayerData.Instance.TemplateId.ToString() + "_mobile";}}Debug.Log("SceneName TemplateId:" + SceneName);
#if UNITY_EDITORif (AppConst.UseAssetBundle) {yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);}else {yield return SceneManager.LoadSceneAsync(SceneName);}#elseyield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
#endif}/// <summary>/// 发布态场景加载完成/// </summary>/// <param name="arg0"></param>/// <param name="arg1"></param>private void OnPublishModeSceneLoadSuccess(Scene arg0, LoadSceneMode arg1) {UIManager.Instance.PushPanel(UIPanelType.EDITOR_MODE_PANEL);UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);EventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);HttpHelper.Instance.GetDefaultSpaceImg();SceneModel.Instance.setDefaultSceneConfig();if (PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>()) {PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>().publicModeForName();PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>().isShowOwnerObj(true);}if (SceneModel.Instance.useGlb) {EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });}}public void OnSceneLoad(object sender, EventArgs e) {if (sceneIsLoaded == true) {return;}sceneIsLoaded = true;var arg = e as SceneLoadActionArgs;Debug.Log("OnSceneLoad:" + arg.state);if (arg.state == AppConst.PublicMode) //创建态{SceneManager.sceneLoaded += OnPublishModeSceneLoadSuccess;}else { //浏览态SceneManager.sceneLoaded += OnViewSceneLoadOk;}StartCoroutine(coLoadSceneAsync());}/// <summary>/// 浏览态场景加载完成/// </summary>/// <param name="arg0"></param>/// <param name="arg1"></param>private void OnViewSceneLoadOk(Scene arg0, LoadSceneMode arg1) {EventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);if (PlayerData.Instance.isRunningPC == true) {UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);}//ToastPanel.Show("OnViewSceneLoadOk");//AlertPanel.Show("OnViewSceneLoadOk", null);//Debug.Log("DownLoadScenConfig");//if (HttpHelper.Instance != null)//{// HttpHelper.Instance.GetDefaultSpaceImg();// //HttpHelper.Instance.DownLoadScenConfig(); //挪到登陆的时候请求场景数据//}if (SceneModel.Instance.useGlb) {EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });}if (PlayerData.Instance.isRunningPC) {SceneModel.Instance.ImplementComLoder();UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);}else {if (SceneModel.Instance.useGlb) {EventManager.Instance.AddListener(EventName.onGlbSceneLoadOK, (s, e) => {StartCoroutine(waitSeconds(1, () => {UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);}));});StartCoroutine(waitSeconds(1, () => {if (SceneModel.Instance.useGlb) {EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });}}));}else {StartCoroutine(waitSeconds(1, () => {UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);}));}}}private IEnumerator waitSeconds(float scecond, Action call) {yield return new WaitForSeconds(scecond);call();}public virtual void Onlogin() {}}
相关文章:
Unity组件开发--AB包打包工具
1.项目工程路径下创建文件夹:ABundles 2.AB包打包脚本: using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement;public class AssetBundle…...
毕业设计:基于python微博舆情分析系统+可视化+Django框架 K-means聚类算法(源码)✅
毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏) 毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总 🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题ÿ…...
xbox如何提升下载速度?
提高Xbox的下载速度可以通过以下几种方法: 连接稳定的网络:使用有线以太网连接而不是无线连接,因为有线连接通常更稳定且速度更快。 关闭正在运行的游戏和应用程序:运行游戏或应用程序会消耗网络资源和处理能力,关闭它…...
day13 滑动窗口最大值 前K个高频元素
题目1:239 滑动窗口最大值 题目链接:239 滑动窗口最大值 题意 长度为K的滑动窗口从整数数组的最左侧移动到最右侧,每次只移动1位,求滑动窗口中的最大值 不能使用优先级队列,如果使用大顶堆,最终要pop的…...
Unity——VContainer的依赖注入
一、IOC控制反转和DI依赖倒置 1、IOC框架核心原理是依赖倒置原则 C#设计模式的六大原则 使用这种思想方式,可以让我们无需关心对象的生成方式,只需要告诉容器我需要的对象即可,而告诉容器我需要对象的方式就叫做DI(依赖注入&…...
【面试突击】Spring 面试实战
🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…...
【Linux】Ubuntu 22.04 上安装最新版 Nextcloud Hub 7 (28.0.1)
在 Ubuntu 22.04 上安装 PHP 版本 安装多个 PHP 版本的最简单方法是使用来自 Debian 开发人员 Ondřej Sur 的 PPA。要添加此 PPA,请在终端中运行以下命令。如果要从 PPA 安装软件,则需要 software-properties-common 包。它会自动安装在 Ubuntu 桌面上,但可能会在您的 Ubuntu…...
PHP项目如何自动化测试
开发和测试 测试和开发具有同等重要的作用 从一开始,测试和开发就是相向而行的。测试是开发团队的一支独立的、重要的支柱力量。 测试要具备独立性 独立分析业务需求,独立配置测试环境,独立编写测试脚本,独立开发测试工具。没有…...
WEB 3D技术 three.js 3D贺卡(1) 搭建基本项目环境
好 今天 我也是在网上学的 带着大家一起来做个3D贺卡 首先 我们要创建一个vue3的项目、 先创建一个文件夹 装我们的项目 终端执行 vue create 项目名称 例如 我的名字想叫 greetingCards 就是 vue create greetingcards因为这个名录 里面是全部都小写的 然后 下面选择 vue3 …...
短视频IP运营流程架构SOP模板PPT
【干货资料持续更新,以防走丢】 短视频IP运营流程架构SOP模板PPT 部分资料预览 资料部分是网络整理,仅供学习参考。 抖音运营资料合集(完整资料包含以下内容) 目录 抖音15秒短视频剧本创作公式 在抖音这个短视频平台上&#…...
python爬虫之线程与多进程知识点记录
一、线程 1、概念 线程 在一个进程的内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”叫做线程 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指…...
基于Java (spring-boot)的停车场管理系统
一、项目介绍 基于Java (spring-boot)的停车场管理系统、预订车位系统、停车缴费系统功能: 登录、注册、后台首页、用户信息管理、车辆信息管理、新增车辆、车位费用设置、停泊车辆查询、车辆进出管理、登录日志查询、个人中心、预定停车位、缴费信息。 适用人群&…...
微软Office 2019 批量授权版
软件介绍 微软办公软件套件Microsoft Office 2019 专业增强版2024年1月批量许可版更新推送!Office2019正式版2018年10月份推出,主要为多人跨平台办公与团队协作打造。Office2019整合对过去三年在Office365里所有功能,包括对Word、Excel、Pow…...
ChatGLM2-6B 大语言模型本地搭建
ChatGLM模型介绍: ChatGLM2-6B 是清华 NLP 团队于不久前发布的中英双语对话模型,它具备了强大的问答和对话功能。拥有最大32K上下文,并且在授权后可免费商用! ChatGLM2-6B的6B代表了训练参数量为60亿,同时运用了模型…...
WindowsServer安装mysql最新版
安装 下载相应mysql安装包: MySQL :: Download MySQL Installer 选择不登陆下载 双击运行下载好的mysql-installer-community-*.*.*.msi 进入类型选择页面,本人需要mysql云服务就选择了server only server only(服务器)&#x…...
gin切片表单验证
在Gin中对切片进行表单验证的步骤与对其他类型的字段进行验证类似。以下是一些基本步骤,我们可以根据具体的需求进行调整: 定义结构体: 创建一个结构体,用于存储表单数据。确保结构体中的字段类型与你预期的表单数据类型一致。 使…...
openssl3.2 - 官方demo学习 - certs
文章目录 openssl3.2 - 官方demo学习 - certs概述笔记官方的实验流程mkcerts.sh - 整理ocsprun.sh - 整理ocspquery.sh - 整理从mkcerts.sh整理出来的27个.bata1_create_certificate_directly.cmda2_Intermediate_CA_request_first.cmda3_Sign_request_CA_extensions.cmda4_Ser…...
Datawhale 大模型基础理论 Day1 引言
开源链接如下:https://github.com/datawhalechina/so-large-lm/blob/main/docs/content/ch01.md 语言模型的概念:即能够赋予每个有意义的词(token)以一定的概率的一个函数的集合。 语言模型可以被用来评估输入的质量,…...
HarmonyOS应用开发学习笔记 UIAbility组件与UI的数据同步 EventHub、globalThis
1、 HarmoryOS Ability页面的生命周期 2、 Component自定义组件 3、HarmonyOS 应用开发学习笔记 ets组件生命周期 4、HarmonyOS 应用开发学习笔记 ets组件样式定义 Styles装饰器:定义组件重用样式 Extend装饰器:定义扩展组件样式 5、HarmonyOS 应用开发…...
leetcode每日一题44
130. 被围绕的区域 图论 dfs/bfs dfs代码框架 void dfs(参数) {if (终止条件) {存放结果;return;}for (选择:本节点所连接的其他节点) {处理节点;dfs(图,选择的节点); // 递归回溯,撤销处理结果} }思路:本题要求找到被x围绕的陆…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
