一、概述
目前随着市场上的VR设备越来越多,控制器的类型越来越趋向于碎片化。老版的SteamVR插件显然不再适用,因为每当有新的控制器发布就,开发者就需要修改交互代码来适配新的设备,毕竟从开发角度来说,不同的控制器具有独立的键值映射。所以,V社推出了SteamVR2.0,能够让开发者在开发过程中只需要针对于用户的动作而不是控制器的按键。SteamVR2.0的重要更新是加入了Input System,更加符合OpenXR的标准。
Input System和之前处理用户的明显区别为:使用SteamVR Input System,开发者可以在应用程序外定义默认的动作并和按键进行绑定,而不需要设置某一设备的特定按键。这样可以让新的设备快速适应应用程序,无需更改代码。
二、动作管理(Actions)
Input System的核心概念是动作(Actions),steamVR2.0将动作抽象为以下6种类型:
- Boolean类型:此类型的动作只有两种状态:True或False,比如点击UI的动作(InteractUI),只有点击和没点击两种状态。在unity中对应类为:SteamVR_Action_Boolean。
- Single类型:此类型的动作返回0-1之间的数值,比如Trigger键按下到松开的过程。在Unity中对应类为SteamVR_Action_Single。
- Vector2类型:此类型的动作返回Vector2数值,比如TouchPad圆盘键。这样的运动可以控制物体四个方向的运动。在Unity中对应类为SteamVR_Action_Vector2。
- Vector3类型:此类型的动作返回Vector3数值。在Unity中对应类为SteamVR_Action_Vector3。
- Pose类型:此类型的动作能够表示三维空间中的位置和旋转值,一般追踪VR控制器。在Unity中对应类为SteamVR_Action_Pose。
- Skeleton类型:此类型的动作能获取用户握住手柄时的手指关节数组,可以根据返回数据结合手部模型更真实地呈现手在虚拟空间中的姿态。在Unity中对应类为SteamVR_Action_Skeleton。
新版SteamVR的事件在Window->SteamVR Input中管理。窗口如下图:
Action Sets为动作集,插件默认为我们设定了一些,一般默认选择default事件不用更改,如有特殊需求可以自己定义修改或添加。Actions窗口中In为输入事件,Out为输出事件。插件中默认为我们添加了一些事件。在这里我们可以自定义事件名称。点击In下面的加号:
FullActionPath为事件路径,不用管它,Name为事件名,这里我们定义为TouchPadTouch,顾名思义,触摸touchpad键。Type为返回值类型,我们选择boolean;Required不用管它,LocalizedString也填入事件名即可。
设置完毕后点击Save and generate,插件会自动生成一个对应类型的Action类打包成.asset文件,并把类写入到FullActionPath中。
三、更改按键设置
和之前插件不同,新版SteamVR插件需要在独立的“控制器按键设置”中设置按键和事件。通过点击SteamVR Input窗口中的Open binding UI可以打开该窗口。
在控制器按键设置窗口中可以设定使用的控制器类型,比如Vive Controller、Oculus Touch等。
点击创建新按键设置可以创建新的配置方案,点击想要使用的配置中的激活按钮可以替换成目前正在使用的配置。
这里我们直接点击“当前按键设置”中的编辑按钮,进入设置页面:
最上面的“default”等对应我们在unity中设定的动作集,因为刚刚使用了default动作集,所以这里也应该在default中进行设定。底部的按钮顾名思义,这里不再描述。
窗口两边分别为左右手柄的动作设置,当勾选“镜像模式”后,右手柄不再能修改,而是自动匹配左手柄的设置。在设置窗口中为我们展示了控制器上的所有按键,在这里我们可以根据需要修改所有按键对应的动作。
这里我们直接找到控制板,点击右侧的加号:
在弹出窗口中选择点击 “触控板” 按钮
这时触控板设置窗口下面添加了一个名为“触控板”的设置页,如下图。
左面为我们设定了“点击”、“触摸”、“位置”三个动作,右边都是“无”,因为我们还没有为这些动作绑定事件。点击触摸右侧的“无”按钮,选择“TouchPadTouch”即可绑定触摸触控板的动作事件。
再点击“位置”右侧的“无”按钮,选择“TouchPadVector2”事件进行绑定。最终设置如下图:
点击左下角的对勾完成设置,点击“保存个人按键设置”可以将设置另存到个人列表。直接返回也可。
四、开始测试
回到Unity中,现在开始撸代码测试。测试的代码很简单:
SteamVR_Behaviour_Pose poseBehavior;
private void Start()
{
poseBehavior = GetComponent<SteamVR_Behaviour_Pose>();
}
void Update()
{
bool isTouched = SteamVR_Actions.default_TouchPadTouch.GetState(poseBehavior.inputSource);
//SteamVR_Action_Boolean b_Spawn = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("TouchPadTouch");
//bool isTouched = b_Spawn.GetState(poseBehavior.inputSource);
if (isTouched)
{
Debug.Log("触控板被触摸了");
}
}
}
然后我们新建一个场景,将“[CameraRig]”预设体放到场景中,并将场景原摄像机删掉。CameraRig下面分为“Controller (left)”、“Controller (right)”、“Camera”分别对应左右控制器和相机。将测试的脚本添加到想要测试的控制器下面。可以看到控制器上已经挂载一个“SteamVR_Behaviour_Pose”脚本就是我们代码中获取的组件。
另外,打开Window->SteamVR Input Live View窗口可以查看各个动作的绑定情况。
运行测试,可以看到打印情况:
五、总结
可以看到,新版的steamVR插件对于不同的VR控制器开发是很友好的,而获取动作事件也有不同的方式(如上面脚本注释的部分也可以获取动作事件)。这里只进行了基础的介绍和总结,更深层次的内容还需要后续研究。最后,希望VRTK能够早日更新出支持SteamVR2.0的版本。