当前位置: 首页 > 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…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...