[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集补充:制作空洞骑士独有的EventSystem和InputModule
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、制作空洞骑士独有的EventSystem和InputModule
- 总结
前言
hello大家好久没见,之所以隔了这么久才更新并不是因为我又放弃了这个项目,而是接下来要制作的工作太忙碌了,每次我都花了很长的时间解决完一个部分,然后就没力气打开CSDN写文章就直接睡觉去了,现在终于有时间整理下我这半个月都做了什么内容。
那么这一期的标题是什么意思呢?就是我之前漏讲了UI当中非常关键的EventSystem和InputModule,没有这两个组件Unity的UI是不会自动进行UI的导航,点击后的事件啥的,而你创建一个canvas,unity会自动生成了一个eventsystem,但是Input Module则是绑定的是Unity最传统的Input Manager,如果你用过前两三年前unity推出的input system的话,你知道它们是要求你替换到input system独有的input module的,


既然我们是使用插件InControl来作为输入控制,我们也要生成一个空洞骑士独有的UI输入木块。
一、pandas是什么?
首先来创建一个类名字叫HollowKnightInputModule.cs,然后它的代码逻辑整体是根据UnityEngine.EventSystems里面的StandaloneInputModule.cs来写的,如果不了解的话建议先了解一下unity自带的input module的源码。
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;namespace InControl
{[AddComponentMenu("Event/Hollow Knight Input Module")]public class HollowKnightInputModule : StandaloneInputModule{public HeroActions heroActions;public PlayerAction SubmitAction {get{return InputHandler.Instance.inputActions.menuSubmit;}set{}}public PlayerAction CancelAction {get{return InputHandler.Instance.inputActions.menuCancel;}set{}}public PlayerAction JumpAction {get{return InputHandler.Instance.inputActions.jump;}set{}}public PlayerAction CastAction {get{return InputHandler.Instance.inputActions.cast;}set{}}public PlayerAction AttackAction {get{return InputHandler.Instance.inputActions.attack;}set{}}public PlayerTwoAxisAction MoveAction {get{return InputHandler.Instance.inputActions.moveVector;}set{}}[Range(0.1f, 0.9f)]public float analogMoveThreshold = 0.5f;public float moveRepeatFirstDuration = 0.8f;public float moveRepeatDelayDuration = 0.1f;[FormerlySerializedAs("allowMobileDevice")]public new bool forceModuleActive;public bool allowMouseInput = true;public bool focusOnMouseHover;private InputDevice inputDevice;private Vector3 thisMousePosition;private Vector3 lastMousePosition;private Vector2 thisVectorState;private Vector2 lastVectorState;private float nextMoveRepeatTime;private float lastVectorPressedTime;private TwoAxisInputControl direction;public HollowKnightInputModule(){heroActions = new HeroActions();direction = new TwoAxisInputControl();direction.StateThreshold = analogMoveThreshold;}public override void UpdateModule(){lastMousePosition = thisMousePosition;thisMousePosition = Input.mousePosition;}public override bool IsModuleSupported(){return forceModuleActive || Input.mousePresent;}public override bool ShouldActivateModule(){if (!enabled || !gameObject.activeInHierarchy){return false;}UpdateInputState();bool flag = false;flag |= SubmitAction.WasPressed;flag |= CancelAction.WasPressed;flag |= JumpAction.WasPressed;flag |= CastAction.WasPressed;flag |= AttackAction.WasPressed;flag |= VectorWasPressed;if (allowMouseInput){flag |= MouseHasMoved;flag |= MouseButtonIsPressed;}if (Input.touchCount > 0){flag = true;}return flag;}public override void ActivateModule(){base.ActivateModule();thisMousePosition = Input.mousePosition;lastMousePosition = Input.mousePosition;GameObject gameObject = eventSystem.currentSelectedGameObject;if (gameObject == null){gameObject = eventSystem.firstSelectedGameObject;}eventSystem.SetSelectedGameObject(gameObject, GetBaseEventData());}public override void Process(){bool flag = SendUpdateEventToSelectedObject();if (eventSystem.sendNavigationEvents){if (!flag){flag = SendVectorEventToSelectedObject();}if (!flag){SendButtonEventToSelectedObject();}}if (allowMouseInput){ProcessMouseEvent();}}private bool SendButtonEventToSelectedObject(){if (eventSystem.currentSelectedGameObject == null){return false;}if (UIManager.instance.IsFadingMenu){return false;}BaseEventData baseEventData = GetBaseEventData();Platform.MenuActions menuAction = Platform.Current.GetMenuAction(SubmitAction.WasPressed, CancelAction.WasPressed, JumpAction.WasPressed, AttackAction.WasPressed, CastAction.WasPressed);if (menuAction == Platform.MenuActions.Submit){ExecuteEvents.Execute<ISubmitHandler>(eventSystem.currentSelectedGameObject, baseEventData, ExecuteEvents.submitHandler);}else if (menuAction == Platform.MenuActions.Cancel){PlayerAction playerAction = AttackAction.WasPressed ? AttackAction : CastAction;if (!playerAction.WasPressed || playerAction.FindBinding(new MouseBindingSource(Mouse.LeftButton)) == null){ExecuteEvents.Execute<ICancelHandler>(eventSystem.currentSelectedGameObject, baseEventData, ExecuteEvents.cancelHandler);}}return baseEventData.used;}private bool SendVectorEventToSelectedObject(){if (!VectorWasPressed){return false;}AxisEventData axisEventData = GetAxisEventData(thisVectorState.x, thisVectorState.y, 0.5f);if (axisEventData.moveDir != MoveDirection.None){if (eventSystem.currentSelectedGameObject == null){eventSystem.SetSelectedGameObject(eventSystem.firstSelectedGameObject, GetBaseEventData());}else{ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);}SetVectorRepeatTimer();}return axisEventData.used;}protected override void ProcessMove(PointerEventData pointerEvent){GameObject pointerEnter = pointerEvent.pointerEnter;base.ProcessMove(pointerEvent);if (focusOnMouseHover && pointerEnter != pointerEvent.pointerEnter){GameObject eventHandler = ExecuteEvents.GetEventHandler<ISelectHandler>(pointerEvent.pointerEnter);eventSystem.SetSelectedGameObject(eventHandler, pointerEvent);}}private void Update(){direction.Filter(Device.Direction, Time.deltaTime);}private void UpdateInputState(){lastVectorState = thisVectorState;thisVectorState = Vector2.zero;TwoAxisInputControl twoAxisInputControl = MoveAction ?? direction;if (Utility.AbsoluteIsOverThreshold(twoAxisInputControl.X, analogMoveThreshold)){thisVectorState.x = Mathf.Sign(twoAxisInputControl.X);}if (Utility.AbsoluteIsOverThreshold(twoAxisInputControl.Y, analogMoveThreshold)){thisVectorState.y = Mathf.Sign(twoAxisInputControl.Y);}if (VectorIsReleased){nextMoveRepeatTime = 0f;}if (VectorIsPressed){if (lastVectorState == Vector2.zero){if (Time.realtimeSinceStartup > lastVectorPressedTime + 0.1f){nextMoveRepeatTime = Time.realtimeSinceStartup + moveRepeatFirstDuration;}else{nextMoveRepeatTime = Time.realtimeSinceStartup + moveRepeatDelayDuration;}}lastVectorPressedTime = Time.realtimeSinceStartup;}}public InputDevice Device{get{return inputDevice ?? InputManager.ActiveDevice;}set{inputDevice = value;}}private void SetVectorRepeatTimer(){nextMoveRepeatTime = Mathf.Max(nextMoveRepeatTime, Time.realtimeSinceStartup + moveRepeatDelayDuration);}private bool VectorIsPressed{get{return thisVectorState != Vector2.zero;}}private bool VectorIsReleased{get{return thisVectorState == Vector2.zero;}}private bool VectorHasChanged{get{return thisVectorState != lastVectorState;}}private bool VectorWasPressed{get{return (VectorIsPressed && Time.realtimeSinceStartup > nextMoveRepeatTime) || (VectorIsPressed && lastVectorState == Vector2.zero);}}private bool MouseHasMoved{get{return (thisMousePosition - lastMousePosition).sqrMagnitude > 0f;}}private bool MouseButtonIsPressed{get{return Input.GetMouseButtonDown(0);}}}
}
这里涉及到我们InputActions.cs和InputHandler.cs代码相关的:
我们先来到HeroActions.cs,创建好menuUI的按键输入:
using System;
using InControl;public class HeroActions : PlayerActionSet
{public PlayerAction left;public PlayerAction right;public PlayerAction up;public PlayerAction down;public PlayerAction menuSubmit;public PlayerAction menuCancel;public PlayerTwoAxisAction moveVector;public PlayerAction attack;public PlayerAction jump;public PlayerAction dash;public PlayerAction cast;public PlayerAction focus;public PlayerAction quickCast;public PlayerAction openInventory;public HeroActions(){menuSubmit = CreatePlayerAction("Submit");menuCancel = CreatePlayerAction("Cancel");left = CreatePlayerAction("Left");left.StateThreshold = 0.3f;right = CreatePlayerAction("Right");right.StateThreshold = 0.3f;up = CreatePlayerAction("Up");up.StateThreshold = 0.3f;down = CreatePlayerAction("Down");down.StateThreshold = 0.3f;moveVector = CreateTwoAxisPlayerAction(left, right, down, up);moveVector.LowerDeadZone = 0.15f;moveVector.UpperDeadZone = 0.95f;attack = CreatePlayerAction("Attack");jump = CreatePlayerAction("Jump");dash = CreatePlayerAction("Dash");cast = CreatePlayerAction("Cast");focus = CreatePlayerAction("Focus");quickCast = CreatePlayerAction("QuickCast");openInventory = CreatePlayerAction("Inventory");}
}
来到InputHandler.cs当中,我们要做的功能如下,首先当然是添加新的按键绑定AddKeyBinding,还有添加新的默认绑定AddDefaultBinding,特别是我们新建的两个行为PlayerAction的menuCancel和menuSubmit
private void MapKeyboardLayoutFromGameSettings(){AddKeyBinding(inputActions.menuSubmit, "Return");AddKeyBinding(inputActions.menuCancel, "Escape");AddKeyBinding(inputActions.up, "UpArrow");AddKeyBinding(inputActions.down, "DownArrow");AddKeyBinding(inputActions.left, "LeftArrow");AddKeyBinding(inputActions.right, "RightArrow");AddKeyBinding(inputActions.attack, "Z");AddKeyBinding(inputActions.jump, "X");AddKeyBinding(inputActions.dash, "D");AddKeyBinding(inputActions.cast, "F");AddKeyBinding(inputActions.quickCast, "Q");AddKeyBinding(inputActions.openInventory, "I");}private void SetupNonMappableBindings(){inputActions = new HeroActions();inputActions.menuSubmit.AddDefaultBinding(new Key[]{Key.Return});inputActions.menuCancel.AddDefaultBinding(new Key[]{Key.Escape});inputActions.up.AddDefaultBinding(new Key[]{Key.UpArrow});inputActions.down.AddDefaultBinding(new Key[]{Key.DownArrow});inputActions.left.AddDefaultBinding(new Key[]{Key.LeftArrow});inputActions.right.AddDefaultBinding(new Key[]{Key.RightArrow});inputActions.attack.AddDefaultBinding(new Key[]{Key.Z});inputActions.jump.AddDefaultBinding(new Key[]{Key.X});inputActions.dash.AddDefaultBinding(new Key[]{Key.D});inputActions.cast.AddDefaultBinding(new Key[]{Key.F});inputActions.quickCast.AddDefaultBinding(new Key[]{Key.Q});inputActions.openInventory.AddDefaultBinding(new Key[]{Key.I});}private static void AddKeyBinding(PlayerAction action, string savedBinding){Mouse mouse = Mouse.None;Key key;if (!Enum.TryParse(savedBinding, out key) && !Enum.TryParse(savedBinding, out mouse)){return;}if (mouse != Mouse.None){action.AddBinding(new MouseBindingSource(mouse));return;}action.AddBinding(new KeyBindingSource(new Key[]{key}));}
还有就是解决上期忘记讲到的两套Input输入一个是游戏内的输入,一个是过场的输入,当在过场UI阶段,我们就使用过场的输入,屏蔽游戏内的输入,然后是决定UI界面的输入和停止UI界面的输入,完整的代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using GlobalEnums;
using InControl;
using UnityEngine;
using UnityEngine.EventSystems;public class InputHandler : MonoBehaviour
{[SerializeField] public bool pauseAllowed { get; private set; }public bool acceptingInput = true;public bool skippingCutscene;private float skipCooldownTime;private bool isGameplayScene;private bool isMenuScene;public static InputHandler Instance;private GameManager gm;private PlayerData playerData;public InputDevice gameController;public HeroActions inputActions;public BindingSourceType lastActiveController;public InputDeviceStyle lastInputDeviceStyle;public delegate void CursorVisibilityChange(bool isVisible); //指针显示变化时发生的委托public event CursorVisibilityChange OnCursorVisibilityChange;//指针显示变化时发生的事件public bool readyToSkipCutscene;public SkipPromptMode skipMode { get; private set; }public delegate void ActiveControllerSwitch();public event ActiveControllerSwitch RefreshActiveControllerEvent;public void Awake(){Instance = this;gm = GetComponent<GameManager>();inputActions = new HeroActions();acceptingInput = true;pauseAllowed = true;skipMode = SkipPromptMode.NOT_SKIPPABLE;}public void Start(){playerData = gm.playerData;SetupNonMappableBindings();MapKeyboardLayoutFromGameSettings();if(InputManager.ActiveDevice != null && InputManager.ActiveDevice.IsAttached){}else{gameController = InputDevice.Null;}Debug.LogFormat("Input Device set to {0}.", new object[]{gameController.Name});lastActiveController = BindingSourceType.None;}private void Update(){UpdateActiveController();if (acceptingInput){if(gm.gameState == GameState.PLAYING){PlayingInput();}else if(gm.gameState == GameState.CUTSCENE){CutSceneInput();}}}public void UpdateActiveController(){if (lastActiveController != inputActions.LastInputType || lastInputDeviceStyle != inputActions.LastDeviceStyle){lastActiveController = inputActions.LastInputType;lastInputDeviceStyle = inputActions.LastDeviceStyle;if (RefreshActiveControllerEvent != null){RefreshActiveControllerEvent();}}}private void PlayingInput(){}private void CutSceneInput(){if (!Input.anyKeyDown && !gameController.AnyButton.WasPressed){return;}if (skippingCutscene){return;}switch (skipMode){case SkipPromptMode.SKIP_PROMPT: //确认跳过过场if (!readyToSkipCutscene){//TODO:gm.ui.ShowCutscenePrompt(CinematicSkipPopup.Texts.Skip);readyToSkipCutscene = true;CancelInvoke("StopCutsceneInput");Invoke("StopCutsceneInput", 5f * Time.timeScale);skipCooldownTime = Time.time + 0.3f;return;}if(Time.time < skipCooldownTime){return;}CancelInvoke("StopCutsceneInput");readyToSkipCutscene = false;skippingCutscene = true;gm.SkipCutscene();return;case SkipPromptMode.SKIP_INSTANT://立刻跳过过场skippingCutscene = true;gm.SkipCutscene();return;case SkipPromptMode.NOT_SKIPPABLE: //不准跳过过场return;case SkipPromptMode.NOT_SKIPPABLE_DUE_TO_LOADING: //在过场视频加载的时候不准跳过过场gm.ui.ShowCutscenePrompt(CinematicSkipPopup.Texts.Skip);CancelInvoke("StopCutsceneInput");Invoke("StopCutsceneInput", 5f * Time.timeScale);break;default:return;}}private void StopCutsceneInput(){readyToSkipCutscene = false;gm.ui.HideCutscenePrompt();}private void MapKeyboardLayoutFromGameSettings(){AddKeyBinding(inputActions.menuSubmit, "Return");AddKeyBinding(inputActions.menuCancel, "Escape");AddKeyBinding(inputActions.up, "UpArrow");AddKeyBinding(inputActions.down, "DownArrow");AddKeyBinding(inputActions.left, "LeftArrow");AddKeyBinding(inputActions.right, "RightArrow");AddKeyBinding(inputActions.attack, "Z");AddKeyBinding(inputActions.jump, "X");AddKeyBinding(inputActions.dash, "D");AddKeyBinding(inputActions.cast, "F");AddKeyBinding(inputActions.quickCast, "Q");AddKeyBinding(inputActions.openInventory, "I");}private void SetupNonMappableBindings(){inputActions = new HeroActions();inputActions.menuSubmit.AddDefaultBinding(new Key[]{Key.Return});inputActions.menuCancel.AddDefaultBinding(new Key[]{Key.Escape});inputActions.up.AddDefaultBinding(new Key[]{Key.UpArrow});inputActions.down.AddDefaultBinding(new Key[]{Key.DownArrow});inputActions.left.AddDefaultBinding(new Key[]{Key.LeftArrow});inputActions.right.AddDefaultBinding(new Key[]{Key.RightArrow});inputActions.attack.AddDefaultBinding(new Key[]{Key.Z});inputActions.jump.AddDefaultBinding(new Key[]{Key.X});inputActions.dash.AddDefaultBinding(new Key[]{Key.D});inputActions.cast.AddDefaultBinding(new Key[]{Key.F});inputActions.quickCast.AddDefaultBinding(new Key[]{Key.Q});inputActions.openInventory.AddDefaultBinding(new Key[]{Key.I});}private static void AddKeyBinding(PlayerAction action, string savedBinding){Mouse mouse = Mouse.None;Key key;if (!Enum.TryParse(savedBinding, out key) && !Enum.TryParse(savedBinding, out mouse)){return;}if (mouse != Mouse.None){action.AddBinding(new MouseBindingSource(mouse));return;}action.AddBinding(new KeyBindingSource(new Key[]{key}));}public void SceneInit(){if (gm.IsGameplayScene()){isGameplayScene = true;}else{isGameplayScene = false;}if (gm.IsMenuScene()){isMenuScene = true;}else{isMenuScene = false;}}public void SetSkipMode(SkipPromptMode newMode){Debug.Log("Setting skip mode: " + newMode.ToString());if (newMode == SkipPromptMode.NOT_SKIPPABLE){StopAcceptingInput();}else if (newMode == SkipPromptMode.SKIP_PROMPT){readyToSkipCutscene = false;StartAcceptingInput();}else if (newMode == SkipPromptMode.SKIP_INSTANT){StartAcceptingInput();}else if (newMode == SkipPromptMode.NOT_SKIPPABLE_DUE_TO_LOADING){readyToSkipCutscene = false;StartAcceptingInput();}skipMode = newMode;}public void StopUIInput(){acceptingInput = false;EventSystem.current.sendNavigationEvents = false;UIManager.instance.inputModule.allowMouseInput = false;}public void StartUIInput(){acceptingInput = true;EventSystem.current.sendNavigationEvents = true;UIManager.instance.inputModule.allowMouseInput = true;}public void StopMouseInput(){UIManager.instance.inputModule.allowMouseInput = false;}public void StartMouseInput(){UIManager.instance.inputModule.allowMouseInput = true;}public void PreventPause(){}public void StopAcceptingInput(){acceptingInput = false;}public void StartAcceptingInput(){acceptingInput = true;}public void AllowPause(){pauseAllowed = true;}}
回到编辑器当中,我们来给UIManager的EventSystem添加上这两个脚本:

总结
OK大功告成,这期算是对前两期的补充内容了,如果你在前两期遇到bug的话可以在这里找下解决办法。
相关文章:
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集补充:制作空洞骑士独有的EventSystem和InputModule
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、制作空洞骑士独有的EventSystem和InputModule总结 前言 hello大家好久没见,之所以隔了这么久才更新并不是因为我又放弃了这个项目,而…...
yelp数据集上试验SVD,SVDPP,PMF,NMF 推荐算法
SVD、SVD、PMF 和 NMF 是几种常见的推荐算法,它们主要用于协同过滤和矩阵分解方法来生成个性化推荐。下面是对每种算法的简要介绍: 1. SVD(Singular Value Decomposition) 用途:SVD 是一种矩阵分解技术,通…...
计算机视觉常用数据集Cityscapes的介绍、下载、转为YOLO格式进行训练
我在寻找Cityscapes数据集的时候花了一番功夫,因为官网下载需要用公司或学校邮箱邮箱注册账号,等待审核通过后才能进行下载数据集。并且一开始我也并不了解Cityscapes的格式和内容是什么样的,现在我弄明白后写下这篇文章,用于记录…...
Flink和Spark在实时计算方面有何异同
Flink和Spark在实时计算方面既有相似之处,也存在显著的差异。以下是对它们之间异同的详细分析: 一、设计理念与世界观 Flink: 专注于流处理,认为批是流的特例。数据流分为有限流(Bounded)和无限流…...
纵然千万数据流逝,唯独vector长存
公主请阅 1.vector的一些方法1vector和stringpush_back 插入以及三种遍历数组的方式一些方法vector中的一些常见的方法1. push_back()2. pop_back()3. size()4. clear()5. empty()6. resize()7. insert()8. erase()9. at()10. front和 back()11. data()12. capacity()13. shrin…...
【LeetCode】【算法】739. 每日温度
LeetCode 739. 每日温度 题目描述 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0…...
2025年知识管理新方案:十款前沿知识库搭建工具详解
随着企业信息化和智能化的发展,知识管理已成为提升企业竞争力的关键要素。一个高效的知识库不仅能促进内部沟通,还能展示企业的专业形象。以下是2025年十款前沿知识库搭建工具的详解。 1. HelpLook AI知识库 HelpLook AI知识库是一款专注于为企业提供高…...
WebSocket实现消息实时推送
文章目录 websocket介绍特点工作原理 用websocket实现实时推送引入依赖WebSocket 函数定义变量声明初始化 WebSocket 连接WebSocket 连接的初始化和事件处理连接打开事件接收消息处理连接关闭和重连机制心跳机制使用 WebSocket代码完整显示 websocket介绍 WebSocket 是一种网络…...
flink 内存配置(三):设置JobManager内存
flink 内存配置(一):设置Flink进程内存 flink 内存配置(二):设置TaskManager内存 flink 内存配置(三):设置JobManager内存 flink 内存配置(四)…...
蓝桥杯 Python组-神奇闹钟(datetime库)
神奇闹钟 传送门: 0神奇闹钟 - 蓝桥云课 问题描述 小蓝发现了一个神奇的闹钟,从纪元时间(1970 年 11 日 00:00:00)开始,每经过 x 分钟,这个闹钟便会触发一次闹铃 (…...
解决阿里云三个月证书过期 免费SSL证书部署教程
相信有上线过自己的网站、小程序经验的同学深有体会,给服务加上 SSL 证书还挺麻烦的,尤其是没有运维经验的同学。本来最省事的方法是买个证书,但是一看价格,还是算了吧,动辄就是几万块一年。作为个人来说,这…...
VBA03-变量
一、什么是变量 变量是一个自定义名称的储存单位,变量是一个载体。 二、代码调试 在代码逐句运行的过程中查看变量的存储内容。 2-1、示例1 2-2、示例 三、变量的数据类型 若是定义的数据类型的变量,存储了超出了她范围的数,则会报溢出。 注…...
docker-ce-stable‘ 下载元数据失败 : Cannot download repomd.xml: Cannot download
看起来你在尝试安装 containerd.io-1.6.32 时遇到了问题,因为 docker-ce-stable 仓库的元数据下载失败。以下是一些可能的解决方案: 1. 检查仓库配置 确保你的 /etc/yum.repos.d/ 目录下的 docker-ce.repo 文件配置正确。你可以尝试手动编辑该文件&…...
C中定义字符串有下列几种形式
字符串常量,char数组,char指针之间的差异 1、字符串常量: 位于一对双括号中的任何字符。双引号里的字符加上编译器自动提供的结束标志\0字符,作为一个字符串存储在内存中。 例如: printf("%s","hello"); /…...
写一个小日历
以下是一个示例,展示了如何创建一个基本的日历 日历 1. HTML 结构 首先,创建一个基本的 HTML 结构,用于展示日历。 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta na…...
【数据库】elasticsearch
1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片(Shard): 将索引数据分割成多个部分,每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理,从而提高系统的扩展性和性能。 在创建索…...
Rust 构建 TCP/UDP 网络服务
第四章 异步编程与网络通信 第二节 构建 TCP/UDP 网络服务 在现代应用程序中,网络通信是核心功能之一。本节将重点介绍如何在 Rust 中构建基本的 TCP 和 UDP 网络服务,涵盖实际的代码示例、最佳实践以及最新的技术方案,以帮助开发者掌握网络…...
docker镜像文件导出导入
1. 导出容器(包含内部服务)为镜像文件(docker commit方法) 原理:docker commit命令允许你将一个容器的当前状态保存为一个新的镜像。这个新镜像将包含容器内所有的文件系统更改,包括安装的软件、配置文件等…...
ViT面试知识点
文章目录 VITCLIPBlipSAMLSegFast TransformerYOLO系列问题 BatchNorm是对一个batch-size样本内的每个特征做归一化,LayerNorm是对每个样本的所有特征做归一化。 Layer Normalization(层归一化,简称LayerNorm)是一种在深度学习中…...
ChatGPT 和 RAG(检索增强生成)的区别;ChatGPT 和 RAG 的联系
目录 ChatGPT 和 RAG(检索增强生成)的区别 知识来源与利用方式 回答准确性和可靠性 模型架构和复杂性 适用场景 ChatGPT 和 RAG 的联系 ChatGPT 和 RAG(检索增强生成)的区别 知识来源与利用方式 ChatGPT:是基于大规模预训练的语言模型,知识是在预训练过程中从大量的…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
