HTC VIVE开发教程(五)
来源:互联网 发布:js div添加class 编辑:程序博客网 时间:2024/05/17 01:23
前面几节我们了解了SteamVR的基本原理,现在可以进行实战开发了。但在进行VR开发前,我还要先介绍一套强大的VR开发工具——VRTK
在进行VIVE开发时,我们经常要用手柄进行一些操作,比如监听按键响应,通过手柄触摸板进行移动,抓取物体等等。这些交互功能实现起来其实不复杂,但是如果我们自己一个个去写又比较麻烦,为了避免重复造轮子,github上便有了vrtk这套SteamVR开发的工具集。
获取vrtk有两种方法
①gitHub的地址:https://github.com/thestonefox/VRTK
②在AssertStore中导入VRTK插件包
但是当我们把VRTK下载下来之后就头疼,这个工具集非常的庞大,由于开发人员也有很多,上面有很多代码甚至是冲突的,也没有一套很详细的说明文档,用起来非常不方便。
所以我们是没必要将这套VR开发工具集全部下载下来的,我们只需要选择里面我们需要的工具类下载下来使用就好了。我选择了下图中几种比较常用的工具类,并且选择几个类来进行源码分析。
第一个常用的工具类是VRTK_ControllerEvents,我们只需要把这个脚本挂到手柄控制器上,就能方便的获取到所有的按键状态。
在介绍这个类之前,我前讲讲我们是如何在SteamVR中获取按键并且响应的。HTC VIVE的手柄如下
HTC手柄的按键数据结构如下
public class ButtonMask { public const ulong System; // 保留按键 public const ulong ApplicationMenu //菜单按钮,对应图中的① public const ulong Grip //手柄按钮,对应图中的⑧ public const ulong Axis0 public const ulong Axis1 public const ulong Axis2 public const ulong Axis3 public const ulong Axis4 public const ulong Touchpad //触控板,对应图中的② public const ulong Trigger //扳机按钮,对应图中的⑦ }
想要获取手柄的按键状态,得先拿到手柄的索引,获取索引有两种方法
①
/*IVRSystem是SteamVR SDK中的一个接口,可以通过OpenVR.System或者SteamVR.hmd来访问,比如获取左手的索引*/IVRSystem.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole unDeviceType)/*获取左手柄的索引*/uint leftIndex=OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.LeftHand);/*获取右手柄的索引*/uint rightIndex = OpenVR.System.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand)
②
/*SteamVR_TrackedObject是挂载在手柄和头显上用来跟踪位置的脚本,在之前的文章中我讲过,这个脚本中记录了当前设备的索引*/uint index=SteamVR_TrackedObject.index;
获取到手柄的索引后,我们就可以在update中通过下面的代码来监听按键了
/*这里的index就是我们前面获取的设备索引*/var device = SteamVR_Controller.Input((int)index);/*这里输入我们之前提到过的按键数据结构SteamVR_Controller.ButtonMask.Trigger 对应扳机键SteamVR_Controller.ButtonMask.ApplicationMenu 对应菜单键……*/device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)
知道了如何监听手柄的按键响应后,我们在来看看这个VRTK_ControllerEvents这个手柄控制工具类
脚本的开头定义了一系列的委托,通过代码可以看到,都是手柄的交互委托,我们只需要注册这些委托事件的回调,就能很方便的获取我们想要监听的按键操作。
我们在来看看它的实现代码
void Update(){ /*因为这个脚本是挂载在手柄下的,所以直接通过SteamVR_TrackedObject来获取索引, trackedController就是SteamVR_TrackedObject脚本*/ controllerIndex = (uint)trackedController.index; device = SteamVR_Controller.Input((int)controllerIndex); /*对于轴设备,则提供了一个GetAxis函数,返回值是一个Vector对象,分别提供X、Y两个维度的轴数据(扳机键 只有X轴这个维度)*/ Vector2 currentTriggerAxis=device.GetAxis(Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger); Vector2 currentTouchpadAxis = device.GetAxis(); /* 在Device里面为每个按键定义了三种状态:Press、PressDown和PressUp。 分别通过GetPress、表示按键是否松开。 对于触摸设备,也定义了GetTouch、GetTouchDown和GetTouchUp三个函数分别获取是否在触摸设备上按下、持续按下及松开。 */ //监听扳机键 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)) { OnTriggerPressed(SetButtonEvent(ref triggerPressed, true, currentTriggerAxis.x)); EmitAlias(ButtonAlias.Trigger, true, currentTriggerAxis.x, ref triggerPressed); } else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger)) { OnTriggerReleased(SetButtonEvent(ref triggerPressed, false, 0f)); EmitAlias(ButtonAlias.Trigger, false, 0f, ref triggerPressed); } else { if (Vector2ShallowEquals(triggerAxis, currentTriggerAxis)) { triggerAxisChanged = false; } else { OnTriggerAxisChanged(SetButtonEvent(ref triggerAxisChanged, true, currentTriggerAxis.x)); } } //监听菜单键 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.ApplicationMenu)) { OnApplicationMenuPressed(SetButtonEvent(ref applicationMenuPressed, true, 1f)); EmitAlias(ButtonAlias.Application_Menu, true, 1f, ref applicationMenuPressed); } else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.ApplicationMenu)) { OnApplicationMenuReleased(SetButtonEvent(ref applicationMenuPressed, false, 0f)); EmitAlias(ButtonAlias.Application_Menu, false, 0f, ref applicationMenuPressed); } //监听抓取键 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Grip)) { OnGripPressed(SetButtonEvent(ref gripPressed, true, 1f)); EmitAlias(ButtonAlias.Grip, true, 1f, ref gripPressed); } else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Grip)) { OnGripReleased(SetButtonEvent(ref gripPressed, false, 0f)); EmitAlias(ButtonAlias.Grip, false, 0f, ref gripPressed); } //监听按压Touchpad if (device.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad)) { OnTouchpadPressed(SetButtonEvent(ref touchpadPressed, true, 1f)); EmitAlias(ButtonAlias.Touchpad_Press, true, 1f, ref touchpadPressed); } else if (device.GetPressUp(SteamVR_Controller.ButtonMask.Touchpad)) { OnTouchpadReleased(SetButtonEvent(ref touchpadPressed, false, 0f)); EmitAlias(ButtonAlias.Touchpad_Press, false, 0f, ref touchpadPressed); } //监听触摸Touched if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Touchpad)) { OnTouchpadTouchStart(SetButtonEvent(ref touchpadTouched, true, 1f)); EmitAlias(ButtonAlias.Touchpad_Touch, true, 1f, ref touchpadTouched); } else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Touchpad)) { OnTouchpadTouchEnd(SetButtonEvent(ref touchpadTouched, false, 0f)); EmitAlias(ButtonAlias.Touchpad_Touch, false, 0f, ref touchpadTouched); } else { if (Vector2ShallowEquals(touchpadAxis, currentTouchpadAxis)) { touchpadAxisChanged = false; } else { OnTouchpadAxisChanged(SetButtonEvent(ref touchpadTouched, true, 1f)); touchpadAxisChanged = true; } } //保存当前触摸板和扳机键的轴数据 touchpadAxis = new Vector2(currentTouchpadAxis.x, currentTouchpadAxis.y); triggerAxis = new Vector2(currentTriggerAxis.x, currentTriggerAxis.y);}
到这里,我们已经了解了如何监听HTC VIVE的手柄按键,也知道了VRTK_ControllerEvents的这个工具类的实现代码,在后面的章节里,我将陆续分析其他几个常用工具类的源码。
- HTC VIVE开发教程(五)
- HTC VIVE开发教程(一)
- HTC VIVE开发教程(二)
- HTC VIVE开发教程(三)
- HTC VIVE开发教程(四)
- HTC VIVE开发教程基础交互功能
- HTC Vive Unity 教程
- HTC Vive Unity 教程
- HTC Vive Unity 教程
- HTC Vive Unity 教程
- VR开发--(HTC Vive)设备一览
- HTC VIVE 开发 移动
- Unity开发HTC VIVE
- Htc Vive开发注意
- HTC Vive VR房产项目开发五(通过材质列表切换地板材质)
- Unity开发HTC vive 五、拾取和触碰
- Unity开发HTC vive 五、拾取和触碰
- HTC VIVE开发初体验
- Android项目中libs库中的armeabi-v7a,armeabi和x86
- 理解A*寻路算法具体过程(转)
- Redis系列~有序集合(sorted set)(十)
- java利用File类和输入输出流实现文件夹的拷贝
- movword [LABEL_DESC_CODE32 + 2], ax
- HTC VIVE开发教程(五)
- android 代码混淆中ProGuard使用详情
- Jquery简单介绍
- BufferedReader和BufferedWriter
- Codevs 2152 滑雪 记忆化搜索DP
- GDI透明贴图
- ShowModalDialog常见的几个问题——表单提交、传值、反馈
- Redis系列~发布订阅(十一)
- Qt ini配置文件