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

Untiy HTC Vive VRTK 开发记录

目录

一.概述

二.功能实现

  1.模型抓取

     1)基础抓取脚本        

     2)抓取物体在手柄上的角度

  2.模型放置区域高亮并吸附

       1)VRTK_SnapDropZone

       2)VRTK_PolicyList

       3)VRTK_SnapDropZone_UnityEvents

  3.交互滑动条

  4.交互旋转模型

  5.设置手柄半透明

三.其他



一.概述

       此篇记录在开发过程中所使用到的VR功能,不针对VRTK或SteamVR的插件进行解释,或导入等等基础内容的说明,如正在开发VR项目或许可以借鉴本篇中解释的相关功能~

二.功能实现

  1.模型抓取

     1)基础抓取脚本        

       给需要被手柄抓取的模型添加图例脚本,必须添加的有VRTK_InteractableObject、VRTK_SwapControllerGrabAction 

       再给手柄添加这些脚本即可,不需要单独去记,因为笔者犯懒,也是直接从VRTK的预制体直接拖拽到场景中的,程序和人有一个能跑就行不是吗~

     2)抓取物体在手柄上的角度

       通常,在抓取到物体的时候,被抓取的物体只是相对于手柄当时的抓取位置被吸附到手柄上,但一般在做项目,比如使用放大镜的时候肯定要保证抓起放大镜的时候保持镜面在最上面,主要是用户体验感上的功能。

       给需要被抓取的物体(笔者这里叫气钻)添加VRTK_TrackObjectGrabAttach,在需要被抓取的物体下创建一个空物体(SnapPoint),给这个空物体添加VRTK_SDKTransformModify。

       在新建的这个空物体下的脚本组件VRTK_SDKTransformModify—Sdk Overrides—Element0—Transform Override Settings中设置位置信息和旋转信息,这里设置的信息会直接覆盖掉被抓取物体相对于手柄的局部位置、局部旋转的信息,建议在运行起来将物体抓到手柄上去调这个参数,最后结束运行复制出来,因为在非运行状态下这个信息很难调。

        最后就是需要将携带VRTK_SDKTransformModify的这个空物体添加到需要被抓取的物体(父物体)的VRTK_TrackObjectGrabAttach—Right Snap Handle中,这个只是代表右手手柄抓起来之后会使用这个空间信息,需要根据项目要求自行选择添加到左手柄还是右手柄。

  2.模型放置区域高亮并吸附

       这个功能主要是使用手柄拾取模型后,需要将这个模型放置到特定的位置上。比如有一条直线,需要用到尺子去测量这条直线的长度,那么在拾取这个尺子在直线附近释放的时候直接将直尺完美贴合到直线上。

       首先在Project文件夹下直接搜索SnapDropZone,将预制体拖拽到场景中。

       可以看到这个预制体上默认携带了碰撞器、刚体、VRTK_SnapDropZone.cs组件,但这些组件还不足以实现高亮和吸附的功能,需要再给这个预制体(SnapDropZone)添加两个脚本,分别为VRTK_PolicyList、VRTK_MaterialColorSwapHighlighter。

       1)VRTK_SnapDropZone

       VRTK_SnapDropZone的作用主要是高亮和吸附的脚本的集成和控制,先主要对两个参数进行修改,分别是Highlight Object Prefab、Highlight Color。

  • Highlight Object Prefab用于在当前区域绘制高亮,类型是GameObject,就是说你他的高亮信息就是你往这个参数里拖拽的任何物体,如果是空物体那什么也没有,如果有网格那就对网格高亮。
  • Highlight Color高亮颜色,类型是Color,直接设置成自己喜欢的高亮颜色就行了。

       关于高亮颜色也可以添加VRTK_MaterialColorSwapHighlighter脚本,在这个脚本上添加材质球会直接覆盖掉VRTK_SnapDropZone的Highlight Color参数。因为项目中可能会有大量的VRTK_SnapDropZone脚本,那么如果策划说高亮颜色需要从蓝色调整为黄色就得一个个去调整了,所以添加统一的颜色管理对于笔者而言还是很有必要的~

       2)VRTK_PolicyList

       在说VRTK_PolicyList前先要说一下这个物体上的碰撞器的作用,在这里碰撞器的大小就是用于判断哪些物体被放置到这个检测范围之内。

       VRTK_PolicyList的作用主要是设置高亮的目标,设置哪些物体进入到这个区域(也就是碰撞器区域)的时候触发高亮,主要判断依据是碰撞器+标签,碰撞器主要检测物体是否进入到这个区域,标签主要检测是哪个物体进入到了这个区域,两者结合在开发起来其实还是比较舒服的,而这个脚本主要就是标签的设置。

       首先给需要进入到这个区域的物体(我这里是气钻)添加并设置一个标签(我这里是Module_3_Qizuan),再给VRTK_PolicyList下的Size—Element0设置一致的标签,最后把它自身给拖拽到VRTK_SnapDropZone组件的Valid Object List Policy中。

       到此,就可以把拖拽物体放置到高亮区域进行高亮的显示了,但实际做项目的时候肯定不能是把这个物体放置到位之后就万事大吉了,所以还需要添加一个将物体放上去之后的事件VRTK_SnapDropZone_UnityEvents,这个添加方式和给Button添加事件没有区别,自己公开一个方法添加即可。

       3)VRTK_SnapDropZone_UnityEvents

       给高亮检测物体添加事件监听脚本VRTK_SnapDropZone_UnityEvents。

  • ObjectEnteredSnapDropZone:对象进入捕捉放置区域
  • ObjectExitedSnapDropZone:对象退出捕捉区域
  • ObjectSnappedToDropZone:捕捉到放置区域的对象
  • ObjectUnsnappedFromDropZone:从放置区域取消捕捉的对象

       一般给ObjectSnappedToDropZone添加事件即可,这个将物体放下吸附上之后会调用,比如我要拿直尺去测量一条直线的长度,那么我的直尺放下之后就会调用具体测量的逻辑代码。

  3.交互滑动条

       使用VRTK脚本VRTK_ArtificialSlider.cs,需要设置的重要参数分别为滑动轴和最大长度,滑动轴用于控制XYZ三个方向的拖拽,

        最大长度用于限制和触发拖拽到终点的事件,这里设置为0.2和0.01,既代表该物体限制x:0.01—0.2之间。

        通过VRTK_BaseControllable.cs脚本给物体添加滑动到最小值和最大值的事件。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK.Controllables;public class TestSlider : MonoBehaviour
{public VRTK_BaseControllable _Controllable;private void OnEnable(){_Controllable.MaxLimitReached += MaxLimitReached;_Controllable.MinLimitReached += MinLimitReached;}protected virtual void MaxLimitReached(object sender, ControllableEventArgs e){Debug.Log("滑动到最大值");}protected virtual void MinLimitReached(object sender, ControllableEventArgs e){Debug.Log("滑动到最小值");}}

  4.交互旋转模型

        需要用到VRTK的脚本为VRTK_ArtificialRotator.cs,需要设置的内容为旋转方向和旋转最小最大值,比交互滑动条需要多设置一个Hinge Point(铰链点),可以理解为需要被旋转的物体是基于这个铰链点的位置信息进行轴的旋转,这个可以帮助我们做一些不规则物体(见下图)的正常旋转(毕竟不能啥玩意都像老年健身区的转盘那样直溜溜的转)


        VRTK_ArtificialRotator的重要参数

       通过VRTK_BaseControllable.cs脚本给物体添加旋转到最小值和最大值的事件。因为代码写的太烂大家自行参考自带案例025_Controls_Overview,只对这个功能的实现逻辑大概说一下,是通过VRTK_Control_UnityEvents.cs的OnValueChanged获取旋转量,通过VRTK_BaseControllable来处理旋转量。

  5.设置手柄半透明

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK;public class _Device : MonoBehaviour
{public GameObject 传入右手物体RightController;public GameObject 传入左手物体LeftController;IEnumerator Start(){yield return new WaitForSeconds(1);VRTK_ObjectAppearance.SetOpacity(VRTK_DeviceFinder.GetModelAliasController(传入右手物体RightController), 0.5f);VRTK_ObjectAppearance.SetOpacity(VRTK_DeviceFinder.GetModelAliasController(传入左手物体LeftController), 0.5f);}}

三.其他

        这里记录使用VR开发遇到的一些问题

        1.因为需求是左手柄有UI持续跟随悬浮,所以在左手柄的子物体列表下添加了可交互UI,而右手柄无法对UI进行交互,左手柄本身做一些尝试可以进行交互,解决方案是通过Update持续更新UI的位置在左手柄下。

        2.手柄半透明的脚本因为写在了Start下,在启动软件的时候刚好手柄丢失定位的情况下会导致手柄的半透明设置失效,我这里写了协程延迟Start一秒,逻辑不严谨建议不要照搬。

        3.尽量不要做UI持续在相机上的功能,因为体验感极差....如果非要做的话尽量让UI往屏幕下方下调一些。如果为了第三者在屏幕观看效果的话尽量让UI向上调,另外在屏幕上观看只能看到右眼的画面,和头盔左右眼结合的画面稍有偏离,可以通过SteamVR来调出“显示VR视图—左上角菜单—双眼-xxxxx”的功能。

相关文章:

Untiy HTC Vive VRTK 开发记录

目录 一.概述 二.功能实现 1.模型抓取 1)基础抓取脚本 2)抓取物体在手柄上的角度 2.模型放置区域高亮并吸附 1)VRTK_SnapDropZone 2)VRTK_PolicyList 3)VRTK_SnapDropZone_UnityEvents 3.交互滑动条 4.交互旋…...

机器学习指南:如何学习机器学习?

机器学习 一、介绍 你有没有想过计算机是如何从数据中学习和变得更聪明的?这就是机器学习 (ML) 的魔力!这就像计算机科学和统计学的酷炫组合,计算机从大量信息中学习以解决问题并做出预测,就像人类一样。 …...

使用numpy处理图片——分离通道

大纲 读入图片分离通道堆叠法复制修改法 生成图片 在《使用numpy处理图片——滤镜》中,我们剥离了RGB中的一个颜色,达到一种滤镜的效果。 如果我们只保留一种元素,就可以做到PS中分离通道的效果。 读入图片 import numpy as np import PIL.…...

metartc5_jz源码阅读-yang_rtcpush_on_rtcp_ps_feedback

// (Payload-specific FB messages,有效载荷反馈信息),这个函数处理Payload重传 int32_t yang_rtcpush_on_rtcp_ps_feedback(YangRtcContext *context,YangRtcPushStream *pub, YangRtcpCommon *rtcp) {if (context NULL || pub NULL)return ERROR_RTC…...

计算机毕业设计 | SpringBoot+vue的家庭理财 财务管理系统(附源码)

1,绪论 1.1 项目背景 网络的发展已经过去了七十多年,网络技术的发展,将会影响到人类的方方面面,网络的出现让各行各业都得到了极大的发展,为整个社会带来了巨大的生机。 现在许多的产业都与因特网息息相关&#xff…...

前端面试题集合三(js)

目录 1. 介绍 js 的基本数据类型。2. JavaScript 有几种类型的值?你能画一下他们的内存图吗?3. 什么是堆?什么是栈?它们之间有什么区别和联系?4. 内部属性 [[Class]] 是什么?5. 介绍 js 有哪些内置对象&am…...

ssm基于JAVA的酒店客房管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本酒店客房管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息…...

杨中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

一 、什么是EF Core 什么是ORM 1、说明: 本课程需要你有数据库、SOL等基础知识。 2、ORM: ObjectRelational Mapping。让开发者用对象操作的形式操作关系数据库 比如插入: User user new User(Name"admin"Password"123”; orm.Save(user);比如查询: Book b…...

微信小程序 全局配置||微信小程序 页面配置||微信小程序 sitemap配置

全局配置 小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。 以下是一个包含了部分常用配置选项的 app.json : {"pages": ["pages/index/index",&q…...

使用ffmpeg对视频进行静音检测

1 原始视频信息 通过ffmpeg -i命令查看视频基本信息 ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developersbuilt with gcc 12.2.0 (Rev10, Built by MSYS2 project)configuration: --enable-gpl --enable-version3 --enable-sta…...

Servlet-Request

一、预览 在上一篇Servlet体系结构中,我们初步了解了怎么快速本篇将介绍Servlet中请求Request的相关内容,包括Request的体系结构,Request常用API。 二、Request体系结构 我们注意到我们定义的Servlet类若实现Servlet接口时,请求…...

数据结构-怀化学院期末题(490)

哈希查找 题目描述: 实现哈希查找。要求根据给定的哈希函数进行存储,并查找相应元素的存储位置。本题目使用的哈希函数为除留取余法,即H(key)key%m,其中m为存储空间,冲突处理方法采用开放定址法中的线性探测再散列&am…...

Matlab字符识别实验

Matlab 字符识别OCR实验 图像来源于屏幕截图,要求黑底白字。数据来源是任意二进制文件,内容以16进制打印输出,0-9a-f’字符被16个可打印字符替代,这些替代字符经过挑选,使其相对容易被识别。 第一步进行线分割和字符…...

MySQL夯实之路-存储引擎深入浅出

innoDB Mysql4.1以后的版本将表的数据和索引放在单独的文件中 采用mvcc来支持高并发,实现了四个标准的隔离级别,默认为可重复读,并且通过间隙锁(next-key locking)策略防止幻读(查询的行中的间隙也会锁定…...

内存卡为什么会提示格式化,内存卡提示格式化还能恢复吗

对于许多电脑用户来说,执行内存卡格式化操作导致数据丢失是一个常见的问题。在日常生活中,数据丢失的情况并不少见,但内存卡格式化后的数据恢复相对较难。目前,能够使用的方法较少,且成功率较低,但并不是没…...

阅读文献-胃癌

写在前面 今天先不阅读肺癌的了,先读一篇胃癌的文章 文献 An individualized stemness-related signature to predict prognosis and immunotherapy responses for gastric cancer using single-cell and bulk tissue transcriptomes IF:4.0 中科院分区:2区 医学…...

水仙花数(Java解法)

什么是水仙花数? 水仙花数是指一个 3 位数,它每位上的数字的 3 次幂之和等于它本身(例如: 1 5 3 153 ),水仙花数的取值范围在 100~1000 之间。 解题思路: 这个题需要把所以的数字都拿到&…...

vue3 源码解析(3)— computed 计算属性的实现

前言 本文是 vue3 源码分析系列的第三篇文章,主要介绍 vue3 computed 原理。computed 是 vue3 的一个特性,可以根据其他响应式数据创建响应式的计算属性。计算属性的值会根据依赖的数据变化而自动更新,而且具有缓存机制,提高了性…...

Alibaba-> EasyExcel 整理3

1 导入依赖 <!-- easyExcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version >3.2.1</version><exclusions><exclusion><artifactId>poi-ooxml-schemas</art…...

创建组-RibbonGroup

使用实例如下&#xff1a; 1、main中&#xff1a; #include "QRibbonDemo.h" #include <QtWidgets/QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); a.setStyle(new RibbonStyle()); a.setApplicationName(&quo…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...