注意:此入门指南仅适用于 Unity Old Input System!现 SteamVR 支持 New Input System


开发平台:Unity 2019版本以上

头显设备介绍

  • HTC Vive 由HTC与Value联合开发的一款VR头显(虚拟现实头戴式显示器)产品。
  • 支持 SteamVR 技术

配置要求

  • VR主机:(最低配置)含机箱、显示器、键鼠及备用电缆、插线板
  • 显卡:NVIDIA GTX 970/AMD 290 级别或更高(建议参考官网展示信息)
  • 内存:4GB 以上
  • 处理器:因特i5以上
  • USB版本:2.0 及其以上

下载SteamVR

  • 前往 Steam 平台,搜索 Steam VR 下载安装
  • 该工具用于检查虚拟设备连接情况,与设置活动环境。

SteamVR 场景搭建

  • 前往 Unity Asset Store 下载资源 “SteamVR Plugin”

常见交互方式

常见交互方式:一头盔、二手柄、三手柄
思路:

  1. 找到交互手柄,追踪脚本Index查找,在Start()函数中获取追踪脚本
private SteamVR_TrackedObject trackedObj;void Start()
{trackedObj = GetComponent<SteamVR_TrackedObject>();
}
  1. Update()函数中通过控制器找到索引
void Update()
{// 通过控制器获取键位var device = SteamVR_Controller.Input((int)trackedObj.index);// 获取手柄具体某一键位if(device.GetPress(SteamVR_Controller.ButtonMask.Trigger)){print("玩家按下扳机键");}// 通过openvr_api实现调用if(device.GetTouchDown(Value.VR.EVRButtonId.k_Button_SteamVR_Touchpad)){print("玩家按下触摸板");}// 手柄震动反馈if(device.GetHairTrigger()){// 震动灵敏度 0-3999device.TriggerHapticPulse(1000, EVRButtonId.k_EButton_Grip);}
}
  1. 获取不同的按键状态:点击(按下、持续按下、抬起)触摸(开始触摸、持续触摸、结束触摸)
  2. 手柄键位:扳机键(Trigger)、触摸板(TouchPad)、侧键(2个 Grip)、菜单键(Application)、系统键(System)

其他:脚本无法正常调用或运作情况下,重启VR设备即可解决。

SteamVR 触摸板分区

常见触摸板分区效果:计算角度实现不同区域(0~360°)

  1. 初始点位置,判断位置在哪一轴向(x/y轴)
  2. 旋转方向(顺时针、逆时针)
private float GetAngle(Vector2 from, Vector2 to)
{float angle;// 返回角度,不分正负angle = Vector2.Angle(from, to);// 获取两向量夹角Vector3 cross = Vector3.Cross(from, to);return cross.z > 0 ? -angle : angle ;
}
  1. 角度大小 (Unity中支持 0° ~ 180°/-180° ~ 0°)
Vector2 from = new Vector2(0, 0);
Vector2 to = device.GetAxis();
//角度计算
float angle = GetAngle(from, to);
//判断
if(angle > 45 && angle < 135)
{Debug.Log("按下——下");
}

SteamVR 凝视效果

源于封装脚本SteanVR_GazeTracker,通过当前头戴设备发出射线,选中交互。

设备追踪脚本SteamVR_TrackedObject,对Camera组件添加。

实现逻辑:

  1. 查找凝视脚本SteanVR_GazeTracker
  2. 获取凝视组件(Component)
SteamVR_GazeTracker gaze;void Start()
{gaze = GetComponent<SteamVR_GazeTracker>();gaze.GazeOn += GazeOnFunction;gaze.GazeOff -= GazeOffFunction;
}
  1. 调用事件
// 进入凝视状态
private void GazeOnFuncetion(object sender, GazeEventArgs e)
{gameObject.GetComponent<MeshRenderer>().material.color = Color.red;
}// 退出凝视状态
private void GazeOffFunction(object sender, GazeEventArgs e)
{gameObject.GetComponent<MeshRenderer>().material.color = Color.green;
}
  1. 响应逻辑

UI 补充说明

VR世界中不存在平面说法,即UI设计模式为World Space


SteamVR 射线交互

SteamVR_Laser_Pointer:手柄射线脚本

实现逻辑:

  1. 获取手柄射线脚本
  2. 使用射线脚本中的事件机制来完成需求
SteamVR_LaserPoint laserPointer;
void Start()
{laserPointer = GetComponent<SteamVR_LaserPointer>();// 事件机制laserPointer.PointerIn += PointerInFunction;laserPointer.PointerOut += PointerOutFUnction;
}
  1. 事件绑定
// 射线进入时
private void PointerInFunction(object sender, PointerEventArgs e)
{// 判断对象if (e.target.name == "XXX") { Destroy(e.target.gameObject); }if (e.target.name == "OOO") { e.target.GetComponent<MeshRenderer>().color = Color.Red; }
}// 射线离开时
private void PointerOutFunction(object sender, PointerEventArgs e)
{// ......
}

SteamVR 瞬移交互

SteamVR_Teleporter:瞬移交互脚本


SteamVR 拾取交互

实现逻辑:

  1. 获取对手柄脚本SteamVR_TrackedObject的引用
private SteamVR_TrackedObject trackedObj;
private StramVR_Controller.Device device;void Start()
{// 获取当前手柄追踪组件trackedObj = GetComponent<SteamVR_TrackedObject>();// 获取手柄对应索引device = SteamVR_Controller.Input((int)trackedobj.index);
}
  1. 检测物品对象(碰撞检测 - 标签、名称、层级)
  2. 手柄按键响应(一般为侧键)
public GameObject target;void Update()
{if (device.GetPress(SteamVR_Controller.ButtonMask.Trigger)){if(target != null){// 对象使用手柄位置,并设置手柄为父对象target.transform.parent = transform;// 获取刚体,取消重力,启用动力学Rigidbody rig = target.GetComponent<Rigidbody>();rig.useGravity = false;rig.isKinematic = true;}}
}
  1. 抓取:被抓对象与手柄绑定
    绑定:位置变化(刚体有无)
    松开:被抓对象与手柄的绑定解除(恢复刚体)
// 进入碰撞
private void OnTriggerEnter(Collider other)
{// 检测:体积过大物体无法拖拽// 存储触摸的对象target = other.transform.gameObejct;
}// 退出碰撞
private void OnTriggerExit(Collider other)
{target = null;
}

VRTK(开源)

描述:全名 VR ToolKit(虚拟现实工具包) ,负责统一管理各种VR设备SDK,提供开发VR程序的框架。其包含多种VR常用功能,如控制器激光指针、虚拟空间运动、UI、虚拟物体交互等。

开发者角度:仅需配置SDK,无需考虑哪种VR设备。

VRTK 场景搭建

  1. 前往 Assets Store 搜索并下载 VRTK、SteamVR
  2. 导入下载插件
  3. 创建 GameObject 对象,命名VRTKManager,添加脚本VRTK_SDK_Manager.cs,并添加VRTK中SDKSetupsSDKSetupSwitch为子物体
  4. 创建 GameObject 对象,命名VRTKScripts,并创建子物体LeftController,添加VRTK_Control_Events至子物体上。同理复制子物体LefController,重命名为RightController

实现逻辑:

  1. 获取VRTK_ControllerEvents组件
private VRTK_ControllerEvents controller;void Start() {controller = GetComponent<VRTK_ControllerEvents>();controller.TriggerPressed += Controller_TriggerPress;
}void Update() {if (controller.triggerPressed) {print("按下逻辑");}
}
  1. 定义事件
private void Controller_TriggerPressed(object sender, ControllerInteractionEventsArgs e) {throw new System.NotImplementedException();
}

VRTK交互方式

VRTK 瞬移交互

  • 手柄 附加光标指针组件(VRTK_Pointer):用于发射光标指针
    附加 贝塞尔 光标渲染器(VRTK_BezierPointerRenderer):用于绘制曲线光标
    附加 贝塞尔 光标渲染器(VRTK_StraightPointerRenderer):用于绘制直线光标

限制瞬移区域:VRTK_Height_Adjust+Teleport.cs组件中 Taget List Policy 属性。该属性需要添加VRTK_Policy List组件

区域障碍显示:VRTK_Player Area.cs组件

VRTK 拾取交互

被拾取物体:

  1. 附加 Collider组件
  2. 附加 VRTK_InteractableObject.cs组件,并启用属性 Is Grabbable

手柄控制器:

  1. 附加触摸 VRTK_InteractTouch.cs组件
  2. 附加抓取 VRTK_InteractGrab.cs组件

关于抓取选项:(Grab Options)

  • Is Grabblable:是否启用抓取
  • Hold Button To Grab:是否持续抓取
  • Stay Grabbed On Teleport:传送中保持抓取状态
  • Valid Drop(释放物体方式)
    No Drop:抓取后不释放
    Drop AnyWhere:随时释放
  • Grab Override Button:覆盖抓取按钮
  • Grab Attack Mechanic Script:抓取对象
  • Secondary Grab Action Script:抓取行为对象

VRTK 攀爬交互

Window -> VRTK -> Setup Interactable Object 打开 Setup Object 窗口

VRTK_SDK Object Alias:配置Body/Head


  1. 添加VRYKUICanvas组件
    (1)创建 Canvas,并修改 Render Mode 为 World Space
    (2)为 Canvas 添加VRTK_UICanvas.cs组件
    (3)添加 Button
  2. 手柄添加 VRTK_pointer

其他

VRTK_Controller Tooltip:按钮引导显示
VRTK_Controller Events_Unity Events:Unity事件触发方法
VRTK_Interact Touch:触摸脚本
VRTK_Interact Use:射线检测
VRTK_Interact Grab:拾取脚本

被射线检测物体或交互物体脚本需要继承VRTK_InteractableObject,被交互对象不可设置为Static

public class Door : VRTK_InteractableObject {private bool isOpen = false;public override void StartUsing(VRTK_InteractUse currentUsingObject = null) {base.StartUsing(currentUsingObject);transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));if(isOpen) transform.Rotate(new Vector3(0, -90, 0));else transform.Rotate(new Vector3(0, 0, 0));isOpen = !isOpen;}
}

VRTK 材质变更

存储材质数据FloorMatData.cs

using UnityEngine;
using Dot.Tweening;[System.Serializable]
public class FloorMatData {public Material floorMat;public Sprite image;
}

切换材质FloorMatList.cs

using UnityEngine;public class FloorMatList : MonoBehaviour {public Transform imageBg;public bool isShowMat = false;public FloorMatData[] matDataList;public GameObject buttonMat;public GameObject floor;void Start() {}void Update() {}private void Init() {imageBg.localScale = new Vector3(0, 1, 1);foreach(var item in matDataList) {GameObject cloneButton = Instantiate(buttonMat);cloneButton.transform.parent = imageBg;cloneButton.GetComponent<RectTransform>();rect.localPosition = Vector3.zero;rect.localRotation = Quaternion.Euler(Vector3.zero);rect.localSacle = Vector3.zero;cloneButton.GetComponent<Image>().sprite = data.image;cloneButton.GetComponent<Button>().onClick.AddListener(delegate() { OnButtonClick(cloneButton);})}}public void ShowMatList() {if(isShowMat) {imageBg.DOScale(new Vector3(0, 1, 1), 0.3f);}else {imageBg.DOScale(Vector3.one, 0.3f);}isShowMat = !isShowMat;}private void OnButtonClick(GameObject button) {// 修改图片材质floor.GetComponent<MeshRenderer>().material = matDataList[button.transform.GetSiblingIndex()].floorMat;}}

【入门部署】Steam VR 环境部署与基本程序实现说明相关推荐

  1. 手动部署OpenStack之环境部署

    手动部署OpenStack之环境部署 一.虚拟机信息 二.基础环境配置 三.系统环境配置 一.虚拟机信息 1.控制节点ct CPU:双核双线程-CPU虚拟化开启 内存:8G 硬盘:300G+300G( ...

  2. php5.6上部署ecshop,Fecshop 环境部署 以及 安装步骤

    一:安装Fecshop的环境部署: 本文只讲解在Linux下面部署安装Fecshop的步骤,在windows下面不做阐述(需要安装的东西太多,windows下面部署我没有玩过,遇到的问题也不能提供好的 ...

  3. Linux高级实战部署--LNMP生产环境部署(mysql,nginx,php编译安装,项目部署)

    LNMP生产环境部署 一.编译安装 MySQL MySQL 类型 #### 1.MySQL Community Server - MySQL Community Server是社区版本,开源免费,但不 ...

  4. 树莓派Pico入门教程,开发环境的配置和程序的编写

    目录 1.是,树莓派 1.1什么是树莓派Pico 1.2主要特性 2.与众不同的编程方式 2.1MicroPython 2.2 Mu的使用和软件的编写 2.3在树莓派Pico上使用MicroPytho ...

  5. 云服务器(CentOS 7)上面部署Node.js环境

    云服务器(CentOS 7)上面部署Node.js环境 文章目录 云服务器(CentOS 7)上面部署Node.js环境 背景信息 步骤一:部署Node.js环境 部署Node.js环境 步骤二:部署 ...

  6. 实施:GitHub + MarkDown 文档系统的工作环境部署及工作流程说明 | 技术传播

    前段时间有幸参与了开源社区的活动,并且借由 Apache Pulsar 项目实践了 GitHub + MarkDown 的文档开发.在与开源社区的童鞋进行交流的过程中了解到,对于非技术专业的TCer, ...

  7. vTPM环境部署(ubuntu)

    vTPM环境部署(ubuntu) vTPM环境部署ubuntu 安装之前 安装seabios-tpm与libtpms swtpm安装 安装qemu-tpm 启动vTPM 更新: 最近看到seabios ...

  8. Ceph Jewel 10.2.3 环境部署

    本文转自:https://www.cnblogs.com/icloud/p/6115447.html Ceph Jewel 10.2.3 环境部署 Ceph 测试环境部署 本文档内容概要 测试环境ce ...

  9. jar k8s 自己的 部署_微服务架构 - 离线部署k8s平台并部署测试实例

    一般在公司部署或者真实环境部署k8s平台,很有可能是内网环境,也即意味着是无法连接互联网的环境,这时就需要离线部署k8s平台.在此整理离线部署k8s的步骤,分享给大家,有什么不足之处,欢迎指正. 1. ...

最新文章

  1. “30位新生代数字经济人才”选拔开启!@乌镇·世界互联网大会
  2. python基础入门:while 循环
  3. Java学习之Iterator(迭代器)的一般用法(转)
  4. Redis源代码分析-内存数据结构intset
  5. 淮北市成人学计算机学校,安徽淮北市成人学电脑?
  6. 计算机不能启动 无法验证数字签名,win10改win7系统启动后提示:无法验证此文件的数字签名怎么办?...
  7. iOS Class结构分析
  8. jmeter 跨线程执行变量
  9. 苹果公司支付1.13亿美元和解“降速门”指控;三大运营商或于年底联合宣布5G消息商用;DBeaver 7.2.5 发布|极客头条...
  10. Python pickle 反序列化详解
  11. make 及 make clean 的作用
  12. 用户体验设计师到底有多重要
  13. 家居行业数字化建设解决方案
  14. 安装K3s 和 ingress-nginx
  15. 百度地图定位失败,显示经纬度(4.9E-324,4.9E-324),错误码-162
  16. golang 字符串转整形 string 转 int ,go string 转 int
  17. --k和k--的区别
  18. CSDN高校俱乐部“名师高校行”——贵州遵义站
  19. js运动(一)—— sidebar(分享到)
  20. 内容营销:赚钱前提弄明白,何谈赚不到钱?

热门文章

  1. python3 多进程 selenium 不启动浏览器 同时执行多个自动化任务
  2. 期刊印刷时间大概多久
  3. threejs 右下角视角指示器
  4. android 4g网络注册不上去,手机的4G网速慢怎么设置?这恐怕不得行噢!
  5. 浏览器打开pdf,禁止下载打印
  6. Golang 操作单向链表的应用实例
  7. 计算机叫醒服务英语,总算发现叫醒服务英语怎么说
  8. SMPLify-x-master | 复现记录
  9. MayaBatch.py 解读
  10. Keka for Mac(压缩解压工具)中文破解版