十、pico+Unity交互开发教程——射线抓取与更多交互功能

一、回顾与引入

回顾上一篇直接抓取的教程,VR交互一般需要可交互的对象(Interactable)和发起交互的对象(Interactor)。直接抓取和射线抓取的可交互对象无区别,可参考上一篇教程设置组件。两者区别在于发起交互的对象不同,直接抓取使用XR Direct Interactor,而射线抓取使用XR Ray Interactor,它可通过射线检测实现远距离交互。

二、添加射线功能的相关组件

  1. XR Origin下的LeftHand ControllerRightHand Controller物体创建子物体,选择XR -> Ray Interactor(Action-based),并命名为Distance Grab Interactor

  2. 删除子物体上的XR Controller,设置LeftHandRightHandTag以实现左右手切换抓取。

  3. 设置XR Ray Interactor上的射线发射起始点Ray Origin TransformXR Interactor Line Visual的颜色效果,可参考射线交互教程。

  4. DistanceGrabInteractor物体拖到Left/RightHand Controller上的XR Interaction Group中,确保一个Interactor被使用时其他Interactor暂时失效。

在这里插入图片描述

四、设置Interaction Layer Mask 层级,上一篇说过

  1. 运行程序时发现射线射到地面会激活传送,这是因为XR Ray Interactor的Interaction Layer Mask默认是Everything,而地面的Interaction Layer Mask是Teleport,可交互物体默认是Default。将XR Ray Interactor的Interaction Layer Mask改为Default可解决此问题。

  2. 也可分别为直接抓取和射线抓取设立不同的Interaction Layer,以区分可被不同方式抓取的物体。
    在这里插入图片描述

五、防止射线抓取的射线与UI发生交互

  1. 当通过射线抓取物体后朝向UI,会发现手部发出射线并能与UI交互,这是DistanceGrab Interactor发出的射线。
  2. 找到DistancegGrab Interactor物体上的XR Ray Interactor组件,取消勾选Raycast Mask的UI选项,防止远距离抓取的射线与UI发生响应。
    在这里插入图片描述

六、让XR Direct Interactor不对XR Ray Interactor产生干扰(新版XRI不会出现此问题)

  1. 注:此部分针对XR Interaction Toolkit 2.1.1版本,若使用2.3.2或更高版本可跳过。

  2. 当用射线抓取物体后,可能会出现即使按住手柄Grip键不放,也会不小心将另一个物体“吸”过来的问题,这是XR Direct Interactor对XR Ray Interactor产生干扰。

  3. 解决思路是写一个脚本控制,当XR Direct Interactor发挥作用时,将XR Ray Interactor隐藏掉。

  4. 创建脚本GrabRayController,在LeftHand Controller和Right Controller物体上挂载并赋值变量,可解决此问题。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;// 抓取射线控制器类
public class GrabRayController : MonoBehaviour
{// 射线交互器public XRRayInteractor grabRayInteractor;// 直接交互器public XRDirectInteractor grabDirectInteractor;void Update(){// 根据直接交互器选中的可交互对象数量来决定射线交互器是否启用。// 如果直接交互器没有选中任何可交互对象(即数量为0),则启用射线交互器;否则禁用射线交互器。grabRayInteractor.enabled = grabDirectInteractor.interactablesSelected.Count == 0;}
}

七、使抓取的物体不会吸到手上(Force Grab)

  1. 若想在抓取时让物体和手保持一定距离,营造远程操纵物体的感觉,可取消XR Ray Interactor脚本中的Force Grab勾选。
    在这里插入图片描述

  2. 若想让射线射到物体上的点作为实际抓取点,可勾选Dynamic Attach。
    在这里插入图片描述

八、远距离抓取时通过摇杆改变抓取物体的位移和旋转角度(Rotate Anchor Action和Translate Anchor Action)

  1. 在测试射线抓取场景时,发现取消Force Grab后,按下手柄Grip键抓取物体再推动摇杆,物体会发生位移和旋转角度变化,这是由XR Controller(Action-based)和XR Ray Interactor组件的设置引起。
  2. XR Controller(Action-based)上的Rotate Anchor Action和Translate Anchor Action引用了Input System中的Action,可通过查看默认输入配置文件进行设置调整。
  3. XR Ray Interactor上的Anchor Control也与此功能相关。
  4. 当然,如果你不想要远距离抓取时通过摇杆改变抓取物体的位移和旋转角度的功能,就直接将左右手 XR Controller 中的 Rotate Anchor Action 和 Translate Anchor Action 的 Use Reference 取消勾选,然后移除下面新建的 Grab Ray Controller 脚本就行了。
    在这里插入图片描述

但是可以发现,触发 Rotate Anchor 或 Translate Anchor 的时候也会触发其他与摇杆控制有关的动作,比如传送,持续移动。因此我们希望在对远距离抓取物体进行操作时,不会触发该手柄其他和摇杆控制绑定的动作。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;// 抓取射线控制器类
public class GrabRayController : MonoBehaviour
{// 射线交互器public XRRayInteractor grabRayInteractor;// 直接交互器public XRDirectInteractor grabDirectInteractor;// 旋转锚点动作引用public InputActionReference rotateAnchorReference;// 平移锚点动作引用public InputActionReference translateAnchorReference;// 传送激活动作引用public InputActionReference teleportActivateReference;// 移动动作引用public InputActionReference moveReference;// 转向动作引用public InputActionReference turnReference;private void Start(){// 为射线交互器的 selectEntered 事件添加监听器,当抓取开始时调用 OnEnterGrab 方法grabRayInteractor.selectEntered.AddListener(OnEnterGrab);// 为射线交互器的 selectExited 事件添加监听器,当抓取结束时调用 OnExitGrab 方法grabRayInteractor.selectExited.AddListener(OnExitGrab);}private void OnDestroy(){// 在对象销毁时,移除 selectEntered 事件的监听器grabRayInteractor.selectEntered.RemoveListener(OnEnterGrab);// 在对象销毁时,移除 selectExited 事件的监听器grabRayInteractor.selectExited.RemoveListener(OnExitGrab);}private void OnEnterGrab(SelectEnterEventArgs arg){// 禁用传送激活动作DisableAction(teleportActivateReference);// 禁用移动动作DisableAction(moveReference);// 禁用转向动作DisableAction(turnReference);// 启用旋转锚点动作EnableAction(rotateAnchorReference);// 启用平移锚点动作EnableAction(translateAnchorReference);}private void OnExitGrab(SelectExitEventArgs arg){// 启用传送激活动作EnableAction(teleportActivateReference);// 启用移动动作EnableAction(moveReference);// 启用转向动作EnableAction(turnReference);// 禁用旋转锚点动作DisableAction(rotateAnchorReference);// 禁用平移锚点动作DisableAction(translateAnchorReference);}private void EnableAction(InputActionReference actionReference){// 根据动作引用获取输入动作var action = GetInputAction(actionReference);// 如果动作不为空且未启用,则启用该动作if (action!= null &&!action.enabled)action.Enable();}private void DisableAction(InputActionReference actionReference){// 根据动作引用获取输入动作var action = GetInputAction(actionReference);// 如果动作不为空且已启用,则禁用该动作if (action!= null && action.enabled)action.Disable();}private InputAction GetInputAction(InputActionReference actionReference){// 如果动作引用不为空,则返回对应的输入动作,否则返回 nullreturn actionReference!= null? actionReference.action : null;}
}

然后在 LeftHand Controller 和 RightHand Controller 物体上分别挂载这个脚本,并且手动赋值。
在这里插入图片描述

通过以上步骤,我们实现了Unity VR中的射线抓取功能以及更多复杂的交互控制,为VR体验增添了丰富性和真实感。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/455551.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NVR小程序接入平台/设备EasyNVR多个NVR同时管理的高效解决方案

在当今的数字化安防时代,视频监控系统的需求日益复杂和多样化。为了满足不同场景下的监控需求,一种高效、灵活且兼容性强的安防视频监控平台——NVR批量管理软件/平台EasyNVR应运而生。本篇探讨这一融合所带来的创新与发展。 一、NVR监测软件/设备EasyNV…

J.D商品详情,一“网”打尽 —— PHP爬虫API数据获取全攻略

在当今数字化时代,数据已成为最宝贵的资源之一。对于电商平台而言,实时掌握商品的详细信息,如同拥有了解锁市场动态的金钥匙。J.D,作为中国领先的电商平台,其商品详情数据的获取,更是电商领域的一大热点。本…

麒麟V10、UOS系统实现在线合并多个Word文件

不管是将多个Word文件插入到Word模板指定位置,生成一个合并文档,还是将多个Word文档插入到一个空白的Word文件中,首尾连接成一篇文档,都需要用到PageOffice提供的数据区域插入Word文档功能。 在实际项目开发中,以下场景…

【前端】如何制作一个自己的网页(18)定义列表

三、定义列表(Definition List) 除了有序和无序列表,还有一种HTML列表类型,被称为定义列表。 应用场景:对某个术语或内容进行解释和描述,所以由标题和描述两部分组成,描述是对标题的解释和说明…

docker harbor

文章目录 一,搭建私有仓库1.1下载registry1.2在 daemon.json 中添加私有镜像仓库地址1.3重新加载重启docker1.4运行容器1.5拉取一个centos7镜像1.6给镜像加标签1.7上传镜像1.8显示私有仓库的所有镜像1.8查看私有仓库的 centos 镜像有哪些tag 二,什么是ho…

Linux Redis查询key与移除日常操作

维护老项目Express node 编写的后端程序、有这么一个方法、没有设置redis过期时间(建议设置过期时间,毕竟登录生产服务器并不是每个人都有权限登录的!!!)。如果变动只能通过登录生产服务器、手动修改… 于…

你还在使用存储过程吗?

上周,reddit 网 r/dotnet 区的网友 technolang 发帖:「你还在使用存储过程吗?」 我很好奇为什么 2024 年了我们还在使用存储过程。难道网络应用中没有一个业务层来处理所有事情吗?依赖 DBA 并在数据库层创建依赖关系似乎没有必要。…

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据) 数据准备:以叶面积指数LAI为例QGis实操:基于GIS4WRF插件将geotiff数据转为tiff警告:GIS4WRF: Input layer had an unexpected …

ONLYOFFICE 文档8.2版本已发布:PDF 协作编辑、改进界面、性能优化等更新

ONLYOFFICE 在线编辑器最新版本已经发布,其中包含30多个新功能和500多个错误修复。阅读本文了解所有更新。 关于 ONLYOFFICE 文档 ONLYOFFICE 是一个开源项目,专注于高级和安全的文档处理。坐拥全球超过 1500 万用户,ONLYOFFICE 是在线办公领…

2024年 Spring Boot 系列学习宝典!!!!!

欢迎来到Spring Boot的世界!本系列文章旨在为开发者提供从入门到精通的全面指导,无论你是Spring Boot新手还是有经验的开发者,都能在这里找到有价值的内容。让我们一起踏上这段旅程,探索如何使用Spring Boot构建高效、可扩展的应用…

Redis底层和缓存雪崩,击穿,穿透

一、Redis的数据结构 1.动态字符串 我们知道Redis中保存的Key是字符串,value往往hi字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。不过,Redis 没有直接使用c语言的字符串,因为c语言字符串存在许多问题: …

蚁剑连接本地木马文件报错

项目场景: 本地搭建php和蚁剑环境,连接本地木马文件ma.php 问题描述 使用蚁剑连接localhost时报错 错误{ "address":"127.0.0.1" "code":"ECONNREFUSED", "errno":"ECONNREFUSED", &qu…

【Kubernetes实战】Kubernetes集群搭建(虚拟机环境,一主两从)

目录 一、 以Node1节点为例创建虚拟机二、 环境初始化三、集群所需组件安装1. docker(18.06.3)2. 安装Kubernetes组件 四、安装Kubernetes集群1. 准备集群镜像2. 集群初始化3. 安装网络插件 五、环境测试(服务部署) 集群规模:一主二从(一个ma…

云计算实验1——基于VirtualBox的Ubuntu安装和配置

实验步骤 1、VirtualBox的安装 本实验使用VirtualBox-7.0.10 进行演示。对于安装包,大家可以前往 VirtualBox官网下载页面(https :/ / www. virtualbox.org/wiki/Downloads)下载其7.0版本安装包进行安装,或者直接使用QQ群的安装包VirtualBox-7.0.10-15…

数字英文验证码识别 API 对接说明

本文将介绍一种 数字英文验证码识别 API 对接说明,它是基于深度学习技术,可用于识别变长英文数字验证码。输入验证码图像的内容,输出验证码结果。 接下来介绍下 数字英文验证码识别 API 的对接说明。 申请流程 要使用 API,需要…

腾讯地图SDK 手势失效或冲突的解决办法

前言 由于高德地图sdk开始涨价割韭菜了,因此,我司在降本增效的大背景下,需要把高德地图换成腾讯地图。 在更换sdk过程中,踩了一些关于地图手势事件的坑,这里记录下,希望能给遇到同样问题的大佬们一个思路。…

21、基于Firefly-rk3399字符设备驱动寄存器控制LED

文章目录 一、电路分析引脚配置功能(R/W register) 二、RK3399数据手册分析:1、GPIO(General-purpose input/output)介绍:2、CRU(Clock & Reset Unit)介绍查找GPIO相关内容: 3、PMU(Power Management Uni)4、GRF(General Regi…

git 报错 SSL certificate problem: certificate has expired

git小乌龟 报错 SSL certificate problem: certificate has expired 场景复现: 原因: 这个错误表明你在使用Git时尝试通过HTTPS进行通信,但是SSL证书已经过期。这通常发生在使用自签名证书或证书有效期已到期的情况下。 解决方法: 1.如果是…

WTN6 E 系列语音芯片 单线时序及示例代码

1. 概述: WTN6 系列为多功能,低功耗,高性能的 CMOS 语音芯片。现有 WTN6020E、WTN6040E、 WTN6080E、WTN6170E 四种芯片(语音长度分别为 20s、40s、80s、170s),已投入市场。 音频采样率目前最高可达 32kHz&#xff0…

streamlit 实现 flink SQL运行界面

实现效果 streamlit flink-playground.py 文件如下: import streamlit as st import io import contextlib import sys import os import uuid import subprocess from jinja2 import Templatest.set_page_config(layout"wide")# 设置页面标题 st.title…