SteamVR插件详解一:SteamVR_Controller脚本

2023-10-15 02:38

本文主要是介绍SteamVR插件详解一:SteamVR_Controller脚本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家都知道现在基于Unity开发Vive的应用程序都需要用到SteamVR这个插件,接下来的系列会重点分析该插件中和开发相关的功能。首先介绍的是Vive手柄控制器开发的介绍,基本包含了手柄功能开发的所有信息。如有不全欢迎补充讨论。使用时需要注意的点我会用绿色标出了,对整个脚本执行过程不感兴趣的可以着重看一下绿色部分,开发时注意就好了。

 

关于控制器的相关信息都包含在SteamVR_Controller这个脚本之中。注意:SteamVR_Controller是非Monobehavior的脚本,并没有挂在场景下,其运行是通过SteamVR_Render脚本对于其中Update()函数的调用从而一直循环获取手柄相关信息。而SteamVR_Render脚本是在程序运行时自动加载至场景的。先来看看脚本的全貌吧。

 

ButtonMask类:手柄各按键的名称。

Device类:最重要的类,封装了跟踪设备的全部信息。

Update()函数:被SteamVR_Render脚本调用,更新各跟踪设备的信息。

Input()函数:根据Index初始化Device[]数组,并实例化所有16个Device。

DeviceRelation和GetDeviceIndex()结合获取特定的设备Index,如leftmost、rightmost。在SteamVR_TestController脚本中有使用到该函数获取用户的左右手手柄的Index。用该方法应该可以识别出用户所拿的手柄是哪一个。

下面着重分析Device类:

  • l  GetPress:按下按键一直触发
  • l  GetPressDown:按下按键只触发一次
  • l  GetPressUp:按下按键只触发一次

针对按键的三个函数,每种函数有两个重载,参数为ButtonMask或EVRButtonId类,第二种形式会将EVRButtonId转换为ButtonMask后调用第一种得到结果。

  • l  GetTouch
  • l  GetTouchDown
  • l  GetTouchUp

针对Touchpad的三个函数,一样的两种形式,同上不解释。

  • l  GetAxis()

获取Touchpad圆盘坐标或Trigger的行程值(0-1),函数默认参数是手柄上的Touchpad。共有5个AxisId参数可选,0是TouchPad,1是Trigger,2,3,4应该是没有用的,且此函数只接受EVRButtonId类参数而不接受ButtonMask。

  • l  TriggerHapticPulse

手柄震动控制函数,参数名称解释的是时间,默认500,但实际上控制的是震动的强度。默认AxisId是EVRButtonId_touchpad,选择其他EVRButtonId没用(等价参数axis0可以),其会调用OpenVR中的同名函数。参数超过4000会无效,导致震动不触发。可以通过协程的while(true)+waitforsecond控制震动间隔,通过stop协程控制震动结束。

  • l  GetHairTrigger
  • l  GetHairTriggerDown定义为有false转至true的过程,判断先前状态和当前状态。
  • l  GetHairTriggerUp 定义为有true转至false的过程,判断先前状态和当前状态。

这三个函数获取HairTrigger的状态,其值对应rAxis1.x的值。But什么是HairTrigger?形象点说就是像头发般轻轻的触发。HairTrigger是检测当你握住扳手超过一个固定值(0.1,可调)时即触发的状态。相当于利用Trigger的变化量来做一个功能的触发,很棒不是吗。轻轻碰一下Trigger使得行程大于0.1即可触发一个功能。

 整个脚本的执行顺序如下:

  • l  Update();
  • l  Input()初始化16个设备的信息存储空间,并返回某个设备;
  • l  Device.Update():做两件事

1.     GetControllerStateWithPose()调用OpenVR中的函数获取手柄状态和姿态。结果存在这两个变量State(VRControllerState_t)和Pose(TrackedDevicePose_t)中,由GetState()和GetPose()获取并由此返回一系列的可查询参数及各种Get函数。

各可查询参数说明如下(相当于对TrackedDevicePose_t中的参数翻译了下)

valid:GetControllerStateWithPose()函数调用是否成功;

connected:判断设备是否连接;

hasTracking:判断设备是否跟踪正常;

 根据ETrackingResult的结果得到下面三个参数:

outOfRange:判断设备是否超出范围;

calibrating:判断设备是否正在校正;

uninitialized:判断设备是否未初始化;

 transform:获取的结果是包含12个元素的一维数组,通过SteamVR_Utils.RigidTransform函数将12个元素重组为3X4矩阵并针对Unity的坐标系进行修正,同时添加了对position和rotation方便的引用。

velocity和angularVelocity:这两个速度也针对Unity的坐标系进行修正,lighthouse跟踪的空间轴方向与Unity存在偏差。

2. UpdateHairTrigger()。检测自定义的一种操作:轻按Trigger。 

TBC:下面几个方面没有深入的研究,有兴趣的童鞋可以研究下,但知道上面的内容后应该已经可以随意访问控制器相关的信息了。

  • 关于DeviceRelation和GetDeviceIndex()没有太多解释,可以深入挖一挖如何使用。

  • ButtonMusk及其他地方有用到很多按位进行的操作,可以补充一下相关知识。

  • Unity环境下空间坐标轴的修正原理没有研究:Unity使用的是左手坐标系,lighthouse的结果应该是右手坐标系,所以才会有速度的z分量相反和角速度x、y分量相反的结果。

 

这篇关于SteamVR插件详解一:SteamVR_Controller脚本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/214817

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMessageDialog()方法 3.1

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

Maven(插件配置和生命周期的绑定)

1.这篇文章很好,介绍的maven插件的。 2.maven的source插件为例,可以把源代码打成包。 Goals Overview就可以查看该插件下面所有的目标。 这里我们要使用的是source:jar-no-fork。 3.查看source插件的example,然后配置到riil-collect.xml中。  <build>   <plugins>    <pl