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的这个工具类的实现代码,在后面的章节里,我将陆续分析其他几个常用工具类的源码。

2 0
原创粉丝点击