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

pico+Unity交互开发——触碰抓取

一、VR交互的类型

  1. Hover(悬停)
    • 定义:发起交互的对象停留在可交互对象的交互区域。例如,当手触摸到物品表面(可交互区域)时,视为触发了Hover。
  2. Grab(抓取)
    • 概念:把物品抓起来。
  3. Use(使用)
    • 基于“抓取”。例如抓取一把枪后,按下枪的扳机发射子弹则视为Use。

三、发起交互的对象(Interactor)

  1. XR Direct Interactor脚本

    • 为了让双手成为发起交互的对象,在LeftHand Controller和RightHand Controller下分别创建Direct Interactor子物体,并添加XR Direct Interactor脚本。
  2. 添加可交互区域

    • XR Direct Interactor需要一个Trigger类型的碰撞体作为可交互区域,且需和它挂载在同一游戏物体上。如在左手和右手的Direct Interactor上分别添加Sphere Collider,调整Radius并勾选Is Trigger。当可交互对象进入该区域后,可进行交互。 ,并设置合适的参数。

在这里插入图片描述

四、可交互的对象(Interactable)创建一个3d对象,比如立方体

  1. 添加刚体

    • 因为手与物品的交互基于物理效果,所以要为可交互物体添加刚体。
    • 在这里插入图片描述
  2. XR Simple Interactable脚本

    • 为方块添加XR Simple Interactable脚本,但是它没有自带抓取的功能。
    • 物体有刚体后该脚本才生效,且挂载脚本的物体还需一个碰撞体。如果是创建的3d对象不需要额外加,如果是自定义模型的话,别忘了手动添加碰撞体
      在这里插入图片描述

2.1、可交互事件

  • 实现功能:
    • 手触碰到方块时,方块颜色改变(模拟Hover,即悬停在可交互区域)。
    • 触碰方块后按下手柄Grip键,方块颜色变成蓝色。
    • 触碰方块后按住Grip键再按Trigger键,方块颜色变回红色。
  • 实现方法:
    • 使用XR Simple Interactable脚本中的Interactable Events
    • 其中Hover Entered对应开始悬停在可交互区域触发的事件,可手动设置更改方块材质。
    • Select EnteredActivated事件分别对应上述第二、三个功能
    • 在Inspector面板中手动绑定事件,Select动作绑定“按下Grip键抓取键”,Activate动作绑定“按下Trigger键扳机键”。 Activate动作以Select动作为前提,Interactable Events中的所有事件以“与可交互对象发生交互”为前提。
      在这里插入图片描述
  1. XR Grab Interactable脚本、和XR Simple Interactable脚本脚本类似,但是有抓取效果;所以需要移除刚刚的XR Simple Interactable脚本

    • Movement Type 移动类型

      • Instantaneous:物体移动位置和姿态完全跟随手的移动,无延迟但无物理刚体效果,物体可穿过碰撞体且碰撞效果非物理。
      • Kinematic:通过Kinematic Rigidbody移动,有延迟,移动中不受力和碰撞作用,但可对其他刚体施加物理效果。
      • Velocity Tracking:通过设置刚体速度和角速度移动,有延迟,有刚体物理效果,可与碰撞体碰撞并对其他刚体产生力的效果。
        在这里插入图片描述
    • Attach Transform 抓取点

      • XR Grab Interactable脚本中有Attach Transform变量可赋值作为抓取点,若未赋值,默认以物体position为抓取点。如抓取枪时,抓取点应在枪柄;
      • 实现功能:可创建枪的子物体Attach Point并赋值给Attach Transform,然后调整其Position位置Rotation以优化抓取效果。但仅设置Attach Transform会有穿模现象,若要实现精细抓取,可参考相关教程。
  2. 代码实现Use功能(制作简易手枪)

    • 核心脚本

      • 创建GunController脚本挂载到枪的游戏物体上。获取XRGrabInteractable中的activated事件,通过AddListener绑定FireBullet函数。
    • 制作子弹预制体

      • 创建子弹Prefab(需刚体和碰撞体),并将子弹Rigidbody的Collision Detection设为Continous Dynamic,防止高速运动时检测不到碰撞。
        在这里插入图片描述
    • 制作子弹发射位置

      • 创建枪的子物体Spawn Point作为子弹生成位置,其z轴箭头方向对应子弹发射方向,将子弹和Spawn Point赋给Gun Controller。
        在这里插入图片描述
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;// 枪支控制器类
public class GunController : MonoBehaviour
{// 子弹预制体public GameObject bullet;// 子弹发射位置的变换组件public Transform spawnPoint;// 子弹发射速度public float fireSpeed = 40;void Start(){// 获取当前物体上的 XRGrabInteractable 组件XRGrabInteractable grabbable = GetComponent<XRGrabInteractable>();// 为 grabbable 的 activated 事件添加监听器,当该事件触发时调用 FireBullet 方法grabbable.activated.AddListener(FireBullet);}private void FireBullet(ActivateEventArgs arg){// 在 spawnPoint 的位置和旋转处实例化子弹预制体GameObject spawnBullet = Instantiate(bullet, spawnPoint.position, spawnPoint.rotation);// 设置实例化出的子弹的刚体速度,使其沿着 spawnPoint 的前方以 fireSpeed 的速度飞行spawnBullet.GetComponent<Rigidbody>().velocity = spawnPoint.forward * fireSpeed;// 在 5 秒后销毁这个子弹对象Destroy(spawnBullet, 5);}
}
  1. 优化一:左右手抓取(判断哪只手与物体交互)
  • 方法一(不推荐)
    • GunController脚本中,给XRGrabInteractableSelectEntered事件绑定ChangeAttachTransform函数,通过判断Interactor是左手还是右手控制器来切换Attach Transform。
      也就是创建两个抓取点,并进行监听ChangeAttachTransform判断左右手、来重新设置抓取点
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;// 枪支控制器类
public class GunController : MonoBehaviour
{// 子弹游戏对象public GameObject bullet;// 子弹发射位置的变换组件public Transform spawnPoint;// 子弹发射速度public float fireSpeed = 40;// 左手抓取点的变换组件private Transform leftHandAttachPoint;// 右手抓取点的变换组件private Transform rightHandAttachPoint;// 当前物体上的可抓取交互组件private XRGrabInteractable grabbable;void Start(){// 在当前物体下查找名为"LeftHand Attach Point"的子物体,获取其变换组件leftHandAttachPoint = transform.Find("LeftHand Attach Point");// 在当前物体下查找名为"RightHand Attach Point"的子物体,获取其变换组件rightHandAttachPoint = transform.Find("RightHand Attach Point");// 获取当前物体上的 XRGrabInteractable 组件grabbable = GetComponent<XRGrabInteractable>();// 为可抓取交互组件的 selectEntered 事件添加监听器,当该事件触发时调用 ChangeAttachTransform 方法grabbable.selectEntered.AddListener(ChangeAttachTransform);// 为可抓取交互组件的 activated 事件添加监听器,当该事件触发时调用 FireBullet 方法grabbable.activated.AddListener(FireBullet);}private void ChangeAttachTransform(SelectEnterEventArgs arg){// 获取触发 selectEntered 事件的交互器的变换组件Transform interactor = arg.interactorObject.transform;// 如果交互器的父物体名称为"Left Controller",表示是左手控制器if (interactor.transform.parent.name == "Left Controller"){// 将当前物体的抓取点设置为左手抓取点grabbable.attachTransform = leftHandAttachPoint;}else if (interactor.transform.parent.name == "Right Controller"){// 如果交互器的父物体名称为"Right Controller",表示是右手控制器// 将当前物体的抓取点设置为右手抓取点grabbable.attachTransform = rightHandAttachPoint;}}private void FireBullet(ActivateEventArgs arg){// 在 spawnPoint 的位置和旋转处实例化子弹游戏对象GameObject spawnBullet = Instantiate(bullet, spawnPoint.position, spawnPoint.rotation);// 获取实例化出的子弹的刚体组件Rigidbody bulletRigidbody = spawnBullet.GetComponent<Rigidbody>();// 设置子弹的速度,使其沿着 spawnPoint 的前方以 fireSpeed 的速度飞行bulletRigidbody.velocity = spawnPoint.forward * fireSpeed;// 在 5 秒后销毁这个子弹对象Destroy(spawnBullet, 5);}
}
  • 方法二减少耦合性
  • 新建脚本XRGrabInteractableTwoAttach继承XRGrabInteractable,重写OnSelectEntered方法,根据Interactor的Tag判断是左手还是右手,切换相应的Attach Transform
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;// 自定义的可抓取交互类,继承自 XRGrabInteractable
public class XRGrabInteractableTwoAttach : XRGrabInteractable
{// 左手的抓取点变换public Transform leftAttachTransform;// 右手的抓取点变换public Transform rightAttachTransform;// 重写 OnSelectEntered 方法,在选择进入时触发protected override void OnSelectEntered(SelectEnterEventArgs args){// 如果交互对象的标签是“Left Hand”(左手)if (args.interactorObject.transform.CompareTag("Left Hand")){// 将当前物体的抓取点设置为左手抓取点attachTransform = leftAttachTransform;}// 如果交互对象的标签是“Right Hand”(右手)else if (args.interactorObject.transform.CompareTag("Right Hand")){// 将当前物体的抓取点设置为右手抓取点attachTransform = rightAttachTransform;}// 调用基类的 OnSelectEntered 方法base.OnSelectEntered(args);}
}

在这里插入图片描述

  • 将枪上的XRGrabInteractable抓取脚本替换为XRGrabInteractableTwoAttach,并在编辑器中为左右手Attach Transform赋值并给Direct Interactor添加Tag

在这里插入图片描述
在这里插入图片描述

  • 第一次抓取或第一次切换抓取位置错误解决方法
    - 方法一
    - 在可抓取物体Gun被抓取物体上添加XRSingleGrabFreeTransformer脚本,游戏运行时会自动添加到XRGrabInteractableTwoAttach脚本。
    在这里插入图片描述

方法二
- 重写刚刚新建的XRGrabInteractableTwoAttach脚本的GetAttachTransform方法,而不是OnSelectEntered方法。根据InteractorTag返回相应的Attach Transform,若Tag不匹配则返回基类的GetAttachTransform结果。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;public class XRGrabInteractableTwoAttach : XRGrabInteractable
{public Transform leftAttachTransform;public Transform rightAttachTransform;public override Transform GetAttachTransform(IXRInteractor interactor){Transform i_attachTransform = null;if (interactor.transform.CompareTag("Left Hand")){i_attachTransform = leftAttachTransform;}if (interactor.transform.CompareTag("Right Hand")){i_attachTransform = rightAttachTransform;}return i_attachTransform != null ? i_attachTransform : base.GetAttachTransform(interactor);}
}

因为之前学的射线交互层级是Everything层级比较高和物体交互层级有重复,所以也能实现射线抓取;然后将与传送有关的 XR Ray Interactor 和 Teleport Area 的 Interaction Layer Mask 改成 Teleport,就可以避免出现这类问题
在这里插入图片描述
在这里插入图片描述

  1. 其他功能一:将与物体接触的地方作为抓取点(Dynamic Attach),也就是碰哪里抓哪里,没有固定抓取点

    • 创建细长Cube作为测试物体,添加碰撞体、刚体和XR Grab Interactable脚本,勾选Use Dynamic Attach后,可根据需求设置Match Position、Match Rotation、Snap To Collider等选项,实现手抓在物体接触部位的效果。

Match Position(匹配位置):当启用相关功能时,确保被抓取物体的位置与抓取点的位置相匹配。例如在使用特定的抓取方式时,可使被抓取物体在被抓取瞬间其位置与抓取点重合,以实现更真实的抓取效果。
Match Rotation(匹配旋转):类似 “匹配位置”,当启用此选项时,被抓取物体的旋转会与抓取点的旋转相匹配。这样可以确保被抓取物体在抓取过程中以合适的角度呈现,增强真实感和交互性。
Snap To Collider(吸附到碰撞体):当开启这个功能后,抓取操作会使被抓取物体吸附到抓取点所在的碰撞体上。这可以使抓取更加精准,并且在抓取过程中物体与抓取点的连接更加紧密,避免出现不合理的位置偏差。

在这里插入图片描述

五、XR Tint Interactable Visual脚本

  1. 功能:可挂载到可交互对象上,当Interactor悬停(Hover)或选中(Select动作触发)可交互对象时,能暂时改变其颜色。
    .在这里插入图片描述2. 设置:调整Tint Color设置颜色,勾选Tint On Hover在Hover时改变颜色,勾选Tint On Selection在Select时改变颜色。注意要把使用的XR Grab Interactable放置到最上层。
    在这里插入图片描述

六、取消身体和可抓取物体的物理碰撞

  1. 设置Layer:将XR Origin的Layer设为Player(仅设置Character Controller所在物体Layer,子物体选No),将所有可抓取物体Layer设为Interactable。
    在这里插入图片描述

  2. 配置Physics:打开Unity编辑器上方菜单栏的Edit编辑 -> Project Settings项目设置-> Physics物理,找到Layer Collision Matrix图层碰撞器,将Player和Interactable的交叉点取消勾选,避免身体与可抓取物体发生物理碰撞。
    在这里插入图片描述

七、XR Interaction Group

  1. 功能:XR Interaction Toolkit 2.3新组件,可管理多个Interactor。当其中一个Interactor生效时,Group内其他Interactor会暂时失效。
    在这里插入图片描述

  2. 应用示例:如在Left/RightHand Controller物体上添加XR Interaction Group组件,将Direct Interactor物体和UI Ray Interactor物体拖到Group中,可实现在抓取物体时让UI射线暂时失效。

八、XR Direct Interactor脚本中的Select Action Trigger

在这里插入图片描述

  1. 参数说明
    • Toggle:以抓取为例,选择Toggle后,靠近物体按下手柄抓取键,物体会被抓在手上,松开抓取键物体仍在手上,下次按下抓取键才会释放。
    • Sticky:按下手柄抓取键物体被抓手上,松开抓取键物体仍在手上,下次按下并松开抓取键物体才会释放。
    • State和State Change的区别(在可抓取物体Select Mode选择Single时)
      • State:可能出现一只手无法接管另一只手抓取权的情况,只有先松开当前抓取手的抓取键才会进行切换抓取。
      • State Change:可以随意切换抓取,推荐在抓取功能上使用State Change。

相关文章:

pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…...

16年408计算机网络

第一题&#xff1a; 解析&#xff1a; 首先我们要清楚R1,R2,R3是路由器&#xff08;网络层&#xff09;&#xff0c;Switch是以太网交换机&#xff08;数据链路层&#xff09;&#xff0c;Hub是集线器&#xff08;物理层&#xff09;。 由此可见路由器实现的最高功能层是3层&am…...

PDF 转 CAD 工具:实现文档格式高效转换的利器

如果你从事设计相关PDF和CAD作为两种常见且重要的文件格式&#xff0c;在不同的领域都有着广泛的应用。今天&#xff0c;我们就来介绍几个各具特色的PDF转换成CAD工具。 1.福昕PDF转换大师 链接一下>>https://www.pdf365.cn/pdf2word/ 该工具在跨领域应用中表现出明确…...

基于springboot的画师约稿系统的设计与实现

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的画师约稿系统的设计与实…...

使用Python生成SVG图片

SVG(可缩放矢量图形)是一种基于XML的图像格式,它可以无损缩放且文件大小较小。在本文中,我们将探讨如何使用Python生成SVG图片。 为什么选择SVG? 可缩放:SVG图像可以无限放大而不失真。文件小:SVG文件通常比位图文件小。可编辑:SVG文件可以通过文本编辑器修改。 使用Python…...

hackmyvm-Hundred靶机

主机发现 sudo arp-scan -l 以sudo权限执行arp-scan -l 扫描并列出本地存在的机器&#xff0c;发现靶机ip为192.168.91.153 nmap扫描 端口发现 21/tcp open ftp 22/tcp open ssh 80/tcp open http web信息收集 我们先尝试一下ftp端口的匿名登录 FTP:是文件传输协议的端…...

多场景多任务建模(三): M2M(Multi-Scenario Multi-Task Meta Learning)

多场景建模: STAR(Star Topology Adaptive Recommender) 多场景建模&#xff08;二&#xff09;: SAR-Net&#xff08;Scenario-Aware Ranking Network&#xff09; 前面两篇文章&#xff0c;讲述了关于多场景的建模方案&#xff0c;其中可以看到很多关于多任务学习的影子&…...

Day31 || 122.买卖股票的最佳时机 II、55. 跳跃游戏、 45.跳跃游戏II 、1005.K次取反后最大化的数组和

122.买卖股票的最佳时机 II 题目链接&#xff1a;力扣题目链接 思路&#xff1a;因为是求虽大利润完全可以假设知道第二天涨前一天买入即可&#xff0c;就是求两天只差大于0 的和。 55. 跳跃游戏 题目链接&#xff1a;力扣题目链接 思路&#xff1a;应该从后往前循环判断&…...

【uniapp】打包成H5并发布

目录 1、设置配置mainifest.sjon 1.1 页面标题 1.2 路由模式 1.3 运行的基础路径 2、打包 2.1 打包入口 2.2 打包成功 2.3 依据目录找到web目录 3、 将web目录整体拷贝出来 4、上传 4.1 登录uniapp官网注册免费空间 4.2 上传拷贝的目录 4.3 检查上传是否正确 5、…...

Position Embedding总结和Pytorch实现

文章目录 出现背景PE位置编码公式思路code 出现背景 自注意力机制处理数据&#xff0c;并不是采用类似RNN或者LSTM那种递归的结构&#xff0c;这使得模型虽然能够同时查看输入序列中的所有元素&#xff08;即并行运算&#xff09;&#xff0c;但是也导致了没办法获取当前word在…...

【AIF-C01认证】亚马逊云科技生成式 AI 认证正式上线啦

文章目录 一、AIF-C01简介二、考试概览三、考试知识点3.1 AI 和 ML 基础知识3.2 生成式人工智能基础3.3 基础模型的应用3.4 负责任 AI 准则3.5 AI 解决方案的安全性、合规性和监管 四、备考课程4.1 「备考训练营」 在线直播课4.2 「SkillBuilder」学习课程 五、常见问题六、参考…...

C++ 素数的筛选法与穷举法

题目:素数大酬宾&#xff1a; 【问题描述】 某商场的仓库中有 n 种商品&#xff0c;每件商品按 1~n 依次编号。现在商场经理突发奇想&#xff0c;决定将编号为素数&#xff08;质数&#xff09;的所有商品拿出来搞优惠酬宾活动。请编程帮助仓库管理员将编号为素数的商品选出来…...

Spring Boot异步任务、任务调度与异步请求线程池的使用及原理

Spring Boot异步任务、任务调度与异步请求线程池的使用及原理 在Spring Boot应用程序中&#xff0c;异步任务、任务调度和异步请求线程池是提高系统性能和响应速度的重要工具。本文将详细讲解这些概念的使用及原理。 一、异步任务 异步任务是指可以在后台线程上执行的任务&a…...

Java爬虫之使用Selenium WebDriver 爬取数据

这里写自定义目录标题 Selenium WebDriver简介一、安装部署二、Java项目中使用1.引入依赖2.示例代码 三、WebDriver使用说明1.WebDriver定位器2.常用操作3.使用 cookie4.键盘与鼠标操作 Selenium WebDriver简介 Selenium WebDriver 是一种用于自动化测试 Web 应用程序的工具。…...

MyBatis 中updateByPrimaryKey和updateByPrimaryKeySelective区别

在 MyBatis 中&#xff0c;updateByPrimaryKey和updateByPrimaryKeySelective主要有以下区别&#xff1a; 一、功能 updateByPrimaryKey&#xff1a; 会根据传入的实体对象&#xff0c;将数据库表中对应主键的记录所有字段全部更新为实体对象中的值。即使实体对象中的某些字段…...

JavaScript下载文件(简单模式、跨域问题、文件压缩)

文章目录 简介简单文件下载通过模拟form表单提交通过XMLHttpRequest方式 跨域(oss)下载并压缩文件完整示例文件压缩跨域设置 简介 相信各位开发朋友都遇到过下载的文件的需求&#xff0c;有的非常简单&#xff0c;基本链接的形式就可以。 有的就比较复杂&#xff0c;涉及跨域…...

Django 定义使用模型,并添加数据

教材&#xff1a; Python web企业级项目开发教程&#xff08;黑马程序员&#xff09;第三章 模型 实验步骤&#xff1a; 1.创建项目和应用 前置步骤可看前文&#xff0c;进入到指定文件位置后创建 django-admin startproject mysite python manage.py startapp app01 2.注册…...

联名物料常泄漏?一端叠满“安全buff”

前段时间&#xff0c;一则关于爆火影视剧与知名茶饮品牌联名的消息在社交平台上迅速传播&#xff0c;宣传物料的照片也随之曝光——门店尚未上新&#xff0c;“小道消息”便已被疯传。但这种情况并非首次发生&#xff0c;让众多网友不禁猜想&#xff1a;这究竟是一场精心策划的…...

Flutter UI组件库(JUI)

Flutter UI组件库 (JUI) 介绍 您是否正在寻找一种方法来简化Flutter开发过程&#xff0c;并创建美观、一致的用户界面&#xff1f;您的搜索到此为止&#xff01;我们的Flutter UI组件库&#xff08;JUI&#xff09;提供了广泛的预构建、可自定义组件&#xff0c;帮助您快速构建…...

国外电商系统开发-运维系统远程文件

设计初衷是为了让所有人都能方便的打开网页&#xff0c;就能查看Linux系统文件内容&#xff0c;而不再用cat、vim、more等命令去打开文件&#xff0c;这对于我们一个普通的研发或者是财务人员来说&#xff0c;显得太繁琐&#xff0c;因为他们很可能不会这些命令&#xff0c;其次…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...