Unity Input System实现单指旋转双指缩放:从原理到实战
1. 项目概述为什么Unity Input System是手势交互的“新基建”在移动端和触屏设备成为主流的今天流畅、自然的手势交互早已不是加分项而是及格线。回想几年前我们还在用Input.touches数组手动计算触点距离和角度写出来的代码既冗长又脆弱多点触控的逻辑耦合在一起调试起来简直是噩梦。现在Unity推出了全新的Input System它不仅仅是一个API的升级更是一套面向现代输入设备从触屏、手柄到XR控制器的标准化、事件驱动的架构。对于需要实现“单指旋转、双指缩放”这类核心手势的场景——无论是AR/VR中的模型查看、移动端策略游戏的镜头控制还是数字孪生中的场景漫游——Input System提供了一套从底层输入抽象到高层动作映射的完整解决方案。这个系统的核心价值在于“解耦”和“声明式配置”。开发者不再需要关心当前是第几根手指在屏幕上也不需要写一堆if (touchCount 2)的判断。你只需要在Input Action Asset中声明一个“Rotate”动作绑定到Touch设备的Delta和一个“Zoom”动作绑定到两个Touch的Position并通过“Vector2 Composite”计算中心点距离变化剩下的脏活累活比如触点追踪、事件派发、跨平台适配Input System都帮你处理好了。这让我们能把精力集中在交互逻辑本身比如旋转的平滑阻尼、缩放的边界限制这才是真正创造用户体验的地方。2. 核心思路拆解Input System如何“理解”手势在动手写代码之前我们必须先理解Input System处理手势的底层逻辑。这能帮你避开很多“想当然”的坑。传统的Input管理器是“轮询式”的你每一帧去问系统“现在有几个触摸点它们在哪”而Input System是“事件式”的它定义了一套清晰的输入“词汇表”Controls控件如一个具体的触摸点、Actions动作如“旋转”、Interactions交互如“按压”、“多点触控”。对于“单指旋转”其本质是一个触点的位移Delta。在Input System中一个Touch控件本身就提供了delta本帧位移、position屏幕坐标等属性。我们只需要将这个delta映射到一个名为“Rotate”的Action上然后在脚本中读取这个Action的值一个Vector2将其转换为物体绕某个轴通常是Y轴的旋转角度即可。这里的关键在于Input System会自动处理触点的开始、移动和结束事件我们无需手动跟踪touchPhase。对于“双指缩放”其本质是两个触点间距离的变化率。Input System没有直接提供一个“Pinch”控件但我们可以通过一个非常巧妙的“Composite复合绑定”来实现。我们可以创建一个“Zoom”动作然后为其添加一个“Vector2 Composite”类型的绑定。这个复合绑定需要两个部分Up和Down。我们可以将Up绑定到第一个触点的Position将Down绑定到第二个触点的Position。这样Input System会自动计算这两个Vector2类型的值并将其组合成一个新的Vector2输出给“Zoom”动作。这个输出的Vector2的y分量在默认的“Vector2 Composite”模式下就代表了Up和Down两点在屏幕空间Y轴方向上的差值。但等等这好像不是我们想要的两点距离这里就是第一个关键点我们需要自定义这个计算逻辑。默认的Vector2Composite提供的是Up - Down的向量差。对于缩放我们需要的是两点之间的距离。因此我们必须放弃使用内置的Vector2Composite而是创建一个自定义的InputBindingComposite在里面计算两个触点position的欧几里得距离。或者更常见的做法是我们不在绑定层做距离计算而是绑定两个触点的位置然后在动作的回调中获取这两个位置值再在代码中实时计算距离变化。后一种方案更灵活也是本项目采用的方案。注意网上很多教程会教你用Touchscreen.primaryTouch和Touchscreen.secondaryTouch但这依赖于系统定义的“主次”触点在快速操作时可能不准确。更稳健的做法是为“Zoom”动作绑定两个独立的Touch控件的Position并通过Part索引如Part1,Part2来区分它们这样我们能明确地获取到两个触点的数据。3. 从零搭建创建Input Action Asset与动作映射理论说再多不如动手。我们打开Unity开始构建我们的手势交互系统。3.1 创建与配置Input Action Asset首先在Project窗口中右键 - Create - Input Actions创建一个新的Input Action Asset命名为TouchControls。双击打开它你会看到三个默认的Action MapsPlayerUIDevice。我们可以清空它们或者直接在里面修改。为了清晰我建议新建一个名为CameraOrbit的Action Map专门用于控制镜头或物体的旋转缩放。在CameraOrbit这个Map下我们创建三个关键的ActionRotate (Value类型 Vector2控制)用于单指旋转。绑定路径Touchscreen/PrimaryTouch/delta。这里我们先使用PrimaryTouch来快速验证逻辑。交互Interactions可以添加一个Press交互设置Press Point为0立即响应这样手指一落下就会开始触发Rotate动作。Zoom (Value类型 Vector2控制)用于双指缩放。这里我们先采用“在代码中计算”的方案。我们需要为这个Action添加两个绑定。第一个绑定路径Touchscreen/touch0/position。在绑定属性中将Part设置为1。这代表我们明确要获取第一个触点的位置。第二个绑定路径Touchscreen/touch1/position。同样将Part设置为2。这样当有两个或以上触点时Zoom动作的读值ReadValueVector2()会返回一个Vector2但其x和y分别对应的是最后一个被激活的绑定的值。为了同时获取两个值我们需要用另一种方式后面会讲。Tap (Button类型)可选的用于单指点击选择或其他功能。绑定到Touchscreen/PrimaryTouch/tap。创建好后记得点击Asset右上角的“Save Asset”按钮。接下来我们需要在场景中启用这套输入系统。3.2 在场景中设置Player Input组件创建一个空物体命名为InputManager。为其添加PlayerInput组件。在组件中Actions拖入我们刚创建的TouchControlsasset。Default Scheme选择Touch。Default Map选择我们创建的CameraOrbit。PlayerInput组件是连接Input Action Asset和你的游戏逻辑的桥梁。它提供了几种通知方式Invoke Events Send Messages Broadcast Messages PlayerInput Component。这里我们选择最灵活、性能也较好的“Invoke Unity Events”。展开PlayerInput组件的事件列表你会看到我们定义的CameraOrbitMap下的所有Action。我们需要为Rotate和Zoom事件挂上对应的处理函数。4. 核心逻辑实现编写手势处理脚本现在我们来创建核心的C#脚本命名为TouchOrbitZoom.cs并将其挂载到需要被旋转/缩放的物体或者控制摄像机的物体上。4.1 脚本结构与初始化using UnityEngine; using UnityEngine.InputSystem; public class TouchOrbitZoom : MonoBehaviour { [Header(旋转控制)] public Transform target; // 围绕旋转的目标点 public float rotationSpeed 5.0f; public bool invertX false; public bool invertY false; private Vector2 _rotationInput; [Header(缩放控制)] public float zoomSpeed 0.1f; public float minDistance 1.0f; public float maxDistance 10.0f; private float _currentZoomDistance 5.0f; private Vector2? _lastTouchPosition1; private Vector2? _lastTouchPosition2; [Header(平滑阻尼)] public float rotationSmoothTime 0.1f; private Vector2 _currentRotationVelocity; private float _currentZoomVelocity; private PlayerInput _playerInput; private InputAction _rotateAction; private InputAction _zoomAction; void Start() { _playerInput FindObjectOfTypePlayerInput(); if (_playerInput null) { Debug.LogError(未在场景中找到PlayerInput组件); return; } // 获取Input Action引用比通过事件字符串查找更高效 _rotateAction _playerInput.actions.FindAction(CameraOrbit/Rotate); _zoomAction _playerInput.actions.FindAction(CameraOrbit/Zoom); if (_rotateAction null || _zoomAction null) { Debug.LogError(未找到对应的Input Action请检查Action Map和Action名称。); } // 初始化距离 _currentZoomDistance Vector3.Distance(transform.position, target.position); } }这里我们做了几件事定义了旋转和缩放所需的参数。使用?声明了可空的Vector2?用于安全地存储上一帧的触点位置。这是处理触点突然消失比如抬起一根手指的关键。引入了“平滑阻尼”SmoothDamp相关的变量用于让旋转和缩放运动更顺滑避免生硬的跳变。在Start中我们通过PlayerInput组件获取了对Rotate和Zoom这两个Action的直接引用。这种方式比在PlayerInput的事件回调中处理更直接也便于我们在Update中持续读取值。4.2 处理单指旋转输入我们不在PlayerInput的事件中直接处理旋转而是每帧去读取RotateAction的值。void Update() { HandleRotation(); HandleZoom(); ApplyTransformation(); } void HandleRotation() { if (_rotateAction ! null) { // 读取当前帧的旋转输入Delta值 Vector2 input _rotateAction.ReadValueVector2(); // 应用反转设置 float x invertX ? -input.x : input.x; float y invertY ? -input.y : input.y; // 使用平滑阻尼让输入值更柔和 _rotationInput Vector2.SmoothDamp(_rotationInput, new Vector2(x, y), ref _currentRotationVelocity, rotationSmoothTime); } }_rotateAction.ReadValueVector2()是关键。当有单指在屏幕上拖动时它会返回一个每帧的位移向量delta。我们将其存储到_rotationInput中并经过平滑处理。4.3 处理双指缩放输入核心难点这是整个系统最需要技巧的部分。我们不能直接读ZoomAction的值因为它绑定了两个位置直接读只会得到一个。我们需要通过InputSystem的API主动去查询当前所有激活的触点。void HandleZoom() { // 获取当前所有触摸 var touches Touchscreen.current?.touches; if (touches null || touches.Count 2) { // 触点少于2个重置记录 _lastTouchPosition1 null; _lastTouchPosition2 null; return; } // 获取前两个有效触点的当前位置 Vector2 currentPos1 touches[0].position.ReadValue(); Vector2 currentPos2 touches[1].position.ReadValue(); if (_lastTouchPosition1.HasValue _lastTouchPosition2.HasValue) { // 计算上一帧和当前帧的两指距离 float previousDistance Vector2.Distance(_lastTouchPosition1.Value, _lastTouchPosition2.Value); float currentDistance Vector2.Distance(currentPos1, currentPos2); // 计算距离变化量并转换为缩放输入 float pinchAmount (currentDistance - previousDistance) * zoomSpeed * 0.01f; // 0.01f用于调整灵敏度 // 更新目标缩放距离 _currentZoomDistance Mathf.Clamp(_currentZoomDistance - pinchAmount, minDistance, maxDistance); } // 记录当前帧位置供下一帧使用 _lastTouchPosition1 currentPos1; _lastTouchPosition2 currentPos2; }逻辑解析Touchscreen.current?.touches获取当前触摸屏设备上所有触点的集合。这是一个ReadOnlyArrayInputControlTouchState。我们检查触点数量是否大于等于2。如果不是则清空上一帧的位置记录直接返回。获取索引为0和1的两个触点的当前位置。在稳定的双指操作下这两个索引通常是可靠的。如果上一帧有记录位置_lastTouchPosition1.HasValue则计算两帧之间两点距离的变化量(currentDistance - previousDistance)。将这个变化量乘以一个灵敏度系数zoomSpeed和0.01f得到本帧的缩放量pinchAmount。注意距离变化是像素值通常很大所以需要乘以一个很小的系数如0.01f来适配你的场景缩放比例。用pinchAmount去更新_currentZoomDistance并用Mathf.Clamp限制在最小最大值之间。最后记录当前帧的位置供下一帧计算。实操心得这里有一个常见的坑——触点索引的稳定性。当第一根手指抬起第二根手指变成touches[0]时如果直接用_lastTouchPosition1旧的第一指和currentPos1新的第一指计算会导致距离计算错误产生剧烈的抖动或跳跃。更健壮的做法是根据触点的唯一IDtouchId进行跟踪而不是依赖数组索引。TouchState里有一个touchId属性。我们可以维护一个字典用touchId作为键来存储和更新每个触点的历史位置。这样即使触点顺序变化也能正确配对计算。这对于要求严苛的生产环境是必要的。本项目为简化起见使用了索引法在大多数循序渐进的交互中表现尚可。4.4 应用变换到物体或摄像机最后我们将计算好的旋转和缩放应用到Transform上。void ApplyTransformation() { if (target null) return; // 1. 应用旋转围绕目标点的轨道旋转 // 这里我们采用让摄像机或物体自身绕目标点旋转的方式 transform.RotateAround(target.position, Vector3.up, _rotationInput.x * rotationSpeed); transform.RotateAround(target.position, transform.right, -_rotationInput.y * rotationSpeed); // 注意Y轴旋转方向 // 2. 应用缩放改变与目标点的距离 Vector3 desiredPosition target.position - transform.forward * _currentZoomDistance; // 使用平滑阻尼让缩放移动更顺滑 transform.position Vector3.Lerp(transform.position, desiredPosition, Time.deltaTime * 10f); // 简单的Lerp也可以用SmoothDamp // 3. 确保镜头始终看向目标 transform.LookAt(target); }步骤解析旋转使用Transform.RotateAround方法。第一个参数是旋转中心点target.position第二个参数是旋转轴。水平旋转_rotationInput.x绕世界坐标的Vector3.upY轴。垂直旋转_rotationInput.y绕摄像机自身的右向量transform.right并取反以使操作符合直觉手指上滑镜头上仰。缩放缩放的本质是改变观察者摄像机与被观察目标之间的距离。我们根据计算出的_currentZoomDistance计算一个期望的位置从目标点出发沿着摄像机当前的前向向量-Z轴的反方向移动_currentZoomDistance的距离。然后用Vector3.Lerp平滑地移动到该位置。注视最后确保摄像机的视线始终对准目标点。5. 性能优化与高级技巧基础功能完成后我们来看看如何让它更健壮、更高效。5.1 使用Input Action回调优化我们之前是在Update中每帧读取Action值。对于Rotate这种连续值动作是合适的。但对于Zoom我们采用了每帧查询Touchscreen.current的方式。另一种更符合Input System哲学的方式是使用Action的回调。我们可以修改脚本void OnEnable() { if (_zoomAction ! null) { // 当Zoom Action的值发生变化时即触点位置变化触发此回调 _zoomAction.performed OnZoomPerformed; } } void OnDisable() { if (_zoomAction ! null) { _zoomAction.performed - OnZoomPerformed; } } void OnZoomPerformed(InputAction.CallbackContext context) { // 问题这里依然无法直接获取两个触点的值。 // 我们需要在回调内部再次查询Touchscreen.current.touches。 // 因此对于需要多点原始数据的场景在Update中查询可能更直接。 }你会发现对于需要同时读取多个独立控件两个触点的位置的情况在performed回调里处理并不比在Update里查询更简洁。因此本项目采用的Update中查询Touchscreen.current.touches的方案对于双指缩放是合理且常见的。5.2 基于TouchId的稳健触点跟踪如前所述依赖数组索引不稳定。下面是改进后的HandleZoom方法片段private Dictionaryint, Vector2 _previousTouchPositions new Dictionaryint, Vector2(); void HandleZoomRobust() { var touches Touchscreen.current?.touches; if (touches null) return; // 收集当前所有活跃触点的ID和位置 Dictionaryint, Vector2 currentTouches new Dictionaryint, Vector2(); foreach (var touchControl in touches) { var touchState touchControl.ReadValue(); if (touchState.phase.IsActive()) // 只处理处于Began, Moved, Stationary状态的触点 { currentTouches[touchState.touchId] touchState.position; } } if (currentTouches.Count 2 _previousTouchPositions.Count 2) { // 将ID转换为列表以便配对这里简单取前两个ID生产环境可能需要更复杂的配对逻辑如寻找最接近的上一帧触点 var currentIds currentTouches.Keys.Take(2).ToList(); var previousIds _previousTouchPositions.Keys.Intersect(currentIds).Take(2).ToList(); if (previousIds.Count 2) { Vector2 lastPos1 _previousTouchPositions[previousIds[0]]; Vector2 lastPos2 _previousTouchPositions[previousIds[1]]; Vector2 currPos1 currentTouches[currentIds[0]]; Vector2 currPos2 currentTouches[currentIds[1]]; float prevDist Vector2.Distance(lastPos1, lastPos2); float currDist Vector2.Distance(currPos1, currPos2); float pinchAmount (currDist - prevDist) * zoomSpeed * 0.01f; _currentZoomDistance Mathf.Clamp(_currentZoomDistance - pinchAmount, minDistance, maxDistance); } } // 更新历史记录 _previousTouchPositions currentTouches; }这个版本通过touchId来唯一标识和跟踪触点避免了因触点索引变化导致的错误。IsActive()方法用于过滤掉已经结束Ended或取消Canceled的触点。5.3 与UI的交互冲突解决一个常见的问题是当手指在UI按钮上滑动时也会触发场景中的旋转缩放。我们需要让UI元素“吃掉”输入事件。Unity的新Input System与EventSystem有很好的集成。确保场景中有EventSystem游戏对象通常创建UI时会自动生成。在PlayerInput组件上勾选UI Input Module部分下的Auto-switch Control Schemes可选并确保你的UI使用了基于Input System的输入模块如Input System UI Input Module组件。最关键的一步在TouchOrbitZoom脚本的Update方法开头或是在处理输入的逻辑前进行检查void Update() { // 检查是否点击在UI上如果是则忽略本次手势输入 if (EventSystem.current ! null EventSystem.current.IsPointerOverGameObject(0)) // 0 代表第一个指针鼠标/触摸 { // 可以在这里重置输入避免UI操作触发场景操作 _rotationInput Vector2.zero; _lastTouchPosition1 null; _lastTouchPosition2 null; return; } HandleRotation(); HandleZoom(); ApplyTransformation(); }EventSystem.current.IsPointerOverGameObject(pointerId)可以判断当前给定指针ID的事件是否发生在UI对象上。对于触摸指针ID就是触摸ID。传入0通常可以检查到第一个或主要的指针事件。这能有效防止UI区域内的触摸干扰3D场景的操控。6. 常见问题与调试技巧实录即使按照步骤操作你也可能会遇到一些“坑”。这里记录了我实战中遇到的一些典型问题及其解决方法。问题1旋转或缩放没有反应。检查点1Input Action Asset绑定是否正确。双击Asset确认Rotate动作是否绑定到了Touchscreen/PrimaryTouch/deltaZoom动作是否绑定了两个Touchscreen/touchX/position。检查点2PlayerInput组件引用和设置。确认InputManager物体上的PlayerInput组件是否正确引用了TouchControlsassetDefault Scheme是否为TouchDefault Map是否为CameraOrbit。检查点3脚本中的Action名称。确认FindAction里传入的字符串路径如”CameraOrbit/Rotate”与Asset中定义的Action Map和Action名称完全一致包括大小写。检查点4输入激活。在Game视图运行时点击顶部菜单栏Window - Analysis - Input Debugger。在Input Debugger中选择你的设备如Touchscreen然后在屏幕上触摸或滑动观察底部是否有相应的事件和值输出。这是排查输入问题最强大的工具。问题2双指缩放时镜头抖动或跳跃。原因极大概率是触点索引配对错误即上一帧的touch[0]和当前帧的touch[0]不是同一根手指。参见5.2节实现基于touchId的跟踪。调试在HandleZoom方法中打印出每一帧两个触点的position和touchId观察在手指交叉滑动时ID是否稳定位置变化是否连续。问题3在UI界面上操作背后的模型还是会动。解决确保已按照5.3节添加了EventSystem.current.IsPointerOverGameObject()检查。注意有些复杂的UI结构或自定义UI可能需要处理多个指针ID。问题4旋转方向不符合直觉比如上下滑动是反转的。调整修改ApplyTransformation方法中RotateAround的旋转轴和正负号。垂直旋转通常用- _rotationInput.y来让手指上滑对应镜头上仰。如果感觉不对去掉负号或调整invertY复选框。问题5WebGL或移动设备上无效。检查确保在Project Settings - Player - Configuration - Active Input Handling设置为Both或Input System Package (New)。旧版Input Manager与新Input System不兼容。构建后移动设备上需要确保屏幕触摸是真正的Touchscreen输入。用Input Debugger连接真机调试是最终手段。一个实用的调试技巧在场景中创建可视化调试信息。void OnGUI() { GUIStyle style new GUIStyle(); style.fontSize 20; style.normal.textColor Color.white; GUI.Label(new Rect(10, 10, 500, 30), $旋转输入: {_rotationInput}, style); GUI.Label(new Rect(10, 50, 500, 30), $当前缩放距离: {_currentZoomDistance:F2}, style); if (_lastTouchPosition1.HasValue _lastTouchPosition2.HasValue) { GUI.Label(new Rect(10, 90, 500, 30), $触点1: {_lastTouchPosition1.Value}, style); GUI.Label(new Rect(10, 130, 500, 30), $触点2: {_lastTouchPosition2.Value}, style); float dist Vector2.Distance(_lastTouchPosition1.Value, _lastTouchPosition2.Value); GUI.Label(new Rect(10, 170, 500, 30), $两指距离: {dist:F2}, style); } }在OnGUI中实时打印关键变量能让你在Game视图里一目了然地看到输入数据快速定位是输入没进来还是逻辑计算有误。这套从Input System基础配置到核心手势算法再到性能优化和问题排查的完整流程基本覆盖了构建一个生产级手势交互系统所需的核心知识。记住关键不在于死记硬背代码而在于理解Input System将输入抽象为“动作”和“控件”的设计思想以及如何处理多点触控这种“多控件”输入的逻辑。剩下的就是根据你的具体项目需求调整参数打磨手感让交互变得跟手、自然。

相关新闻

【关注可白嫖源码】--课程设计--毕业设计-- 生命故事书制作小程序[编号:project65290](案件分析)

【关注可白嫖源码】--课程设计--毕业设计-- 生命故事书制作小程序[编号:project65290](案件分析)

本文仅展示核心实现逻辑与部分代码片段,完整项目源码、配套文档、数据库脚本内容较多,篇幅有限无法全部放出。 有需要完整资源的同学,可以在评论区留言【资料或领源码】,我会一 一回复站内私信,发送完整文件 摘 要 移…

2026/7/26 8:44:15 阅读更多 →
TI 16xx/18xx芯片内存映射与EDMA控制器:释放异构系统数据搬运性能

TI 16xx/18xx芯片内存映射与EDMA控制器:释放异构系统数据搬运性能

1. 项目概述与核心价值在雷达信号处理、高端工业控制或者复杂通信基带这类对实时性要求极高的嵌入式系统中,我们常常会面临一个核心矛盾:一方面,CPU(无论是DSP还是ARM核)需要全力执行复杂的算法和控制逻辑;…

2026/7/26 8:44:15 阅读更多 →
G-Helper完整指南:轻量化华硕笔记本控制工具,释放硬件性能的终极方案

G-Helper完整指南:轻量化华硕笔记本控制工具,释放硬件性能的终极方案

G-Helper完整指南:轻量化华硕笔记本控制工具,释放硬件性能的终极方案 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProA…

2026/7/26 8:43:15 阅读更多 →

最新新闻

如何免费榨取工人的脑力,为埃隆·马斯克的机器人服务

如何免费榨取工人的脑力,为埃隆·马斯克的机器人服务

如何免费榨取工人的脑力,为埃隆马斯克的机器人服务 没有实际经验,打造智能机器人是不可能的,因此科技公司在印度找到了完美的试验场。 工厂工人头戴摄像头,辛勤劳作,录制了数千小时的第一视角视频。 EgoLab 的开发人…

2026/7/26 9:05:25 阅读更多 →
终极指南:如何用Universal x86 Tuning Utility轻松解锁电脑隐藏性能

终极指南:如何用Universal x86 Tuning Utility轻松解锁电脑隐藏性能

终极指南:如何用Universal x86 Tuning Utility轻松解锁电脑隐藏性能 【免费下载链接】Universal-x86-Tuning-Utility Your Hardware. Your Rules. Open. Powerful. Unrestricted Tuning. 项目地址: https://gitcode.com/gh_mirrors/un/Universal-x86-Tuning-Utili…

2026/7/26 9:05:25 阅读更多 →
高效窗口管理神器:AlwaysOnTop让你的Windows窗口永不遮挡

高效窗口管理神器:AlwaysOnTop让你的Windows窗口永不遮挡

高效窗口管理神器:AlwaysOnTop让你的Windows窗口永不遮挡 【免费下载链接】AlwaysOnTop Make a Windows application always run on top 项目地址: https://gitcode.com/gh_mirrors/al/AlwaysOnTop 你是否经常在Windows系统中处理多任务时,重要窗…

2026/7/26 9:05:25 阅读更多 →
【关注可白嫖源码】--课程设计--毕业设计--springboot中老年乙肝肝硬化健康管理系统[编号:project14504](案例分析)

【关注可白嫖源码】--课程设计--毕业设计--springboot中老年乙肝肝硬化健康管理系统[编号:project14504](案例分析)

本文仅展示核心实现逻辑与部分代码片段,完整项目源码、配套文档、数据库脚本内容较多,篇幅有限无法全部放出。 有需要完整资源的同学,可以在评论区留言【资料或领源码】,我会一 一回复站内私信,发送完整文件 摘 要 本…

2026/7/26 9:05:25 阅读更多 →
安卓正在变成苹果,谷歌将限制第三方应用的安装

安卓正在变成苹果,谷歌将限制第三方应用的安装

安卓(Android)正在变成苹果(iOS),谷歌将限制第三方应用的安装 安卓相对于苹果的主要优势正在成为过去。 新的安卓开发者验证规则将要求应用开发者验证身份。 未经验证,第三方应用将无法在智能手机上运行。 普通用户将无法访问第三方软件,…

2026/7/26 9:05:25 阅读更多 →
如何快速优化华硕笔记本性能:G-Helper轻量级控制工具完整指南

如何快速优化华硕笔记本性能:G-Helper轻量级控制工具完整指南

如何快速优化华硕笔记本性能:G-Helper轻量级控制工具完整指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenb…

2026/7/26 9:04:25 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻