SteamVR2.5.0讲解

插件下载地址:https://github.com/ValveSoftware/steamvr_unity_plugin/releases

一、概述

随着越来越多的VR设备推出,控制器类型逐渐趋向于碎片化。每当有新的控制器发布,都会给开发者带来一些额外的工作量——游戏项目需要修改交互代码以适配新的设备。从开发层面上来看,不同的控制器具有不同的键值映射,所以,当现有 VR 应用程序移植到另外一个VR平台的时候,需要针对目标平台进行交互适配。鉴于此, Valve为Unity开发者推出了 SteamVR Unity Plugin 2.0,能够使开发者在编程中专注于用户的动作,而不是具体的控制器按键。

二、重要更新Input System

SteamVR 2.0 的重要更新是加入了 Input System。推出Input System的目的,是为了更加符合OpenXR标准,

Input System与之前处理用户输入有显著的不同,使用SteamVR Input System,开发人员可以在应用程序之外定义默认的动作并与按键进行绑定,而不需要将输入视为某一特定设备的特定按键。这样新的设备可以快速适配应用程序,无需更改代码。比如,当开发者检测玩家是否抓取某个物体的时候,不是检测Vive控制器的Trigger键或Oculus Touch控制器的Grip键是否被按下,而是检测预定义的"Grab"动作是否为True即可。作为开发者,可以在SteamVR中为Grab动作设置默认按键和阈值,当程序运行时,也可修改这些数值以满足玩家的个人偏好。基于这种机制,不光能够解决控制器碎片化的问题,也可以快速适配未来发布的设备。

三、 动作和按键绑定界面

1.导入SteamVR2.5.0插件,Accept All,点击“Window—SteamVR Input—Open binding UI”

2.点击“编辑”进去之后,可对控制器进行按键的修改编辑;

四、动作(Actions):

Input System 的核心概念是动作(Action),基于动作的输入系统对于游戏引擎来说更有意义, Unreal一直在沿用这种方案,而Unity目前在开发中的输入系统也将遵循这一原则。开发者需要放弃之前关于“按下某个按键发生什么事情”的思想,取而代之的是使用“做出某个动作发生什么事情”的思想。

SteamVR 2.0将动作抽象为以下6种类型,简介如下:

(1)Boolean类型的动作代表只有两种状态的动作——True或False,比如抓取(Grab)动作,只有抓取或未抓取两种状态,不存在中间状态。在Unity中对应类为SteamVR_Action_Boolean

(2)Single类型的动作能够返回0~1之间的数值,比如 Trigger 键按下到松开的过程。在Unity中对应类为SteamVR_Action_Single

(3)Vector2类型动作能够返回二维数,比如Touchpad上的触摸或手柄摇杆。使用这样的数值能够控制物体在四个方向的运动,典型的应用时使用Touchpad控制无人机或小车的运动。在Unity中对应类为SteamVR_Action_Vector2

(4)Vector3类型的动作能够返回三维数值,在Unity中对应类为SteamVR_Action_Vector3

(5)Pose类型的动作表示三维空间中的位置和旋转,一般用于跟踪VR控制器。在Unity中对应类为SteamVR_Action_Pose

(6)Skeleton类型的动作能够获取用户在持握手柄控制器时的手指关节数据,通过返回数据,结合手部渲染模型,能够更加真实的呈现手部在虚拟世界的姿态,虽然不及像LeapMotion等设备获取手指输入那样精确,但是足以获得良好的沉浸感。在Unity中对应类为SteamVR_Action_Skeleton

五、振动输出

以上是介绍的都是输入动作,另外,目前还有一种输出动作——振动,用于触发VR控制器上的触觉反馈,调用方法如下代码所示:

SteamVR_Actions.default_Haptic.Execute(float secondsFromNow, float durationSeconds, float frequency, float amplitude, SteamVR_Input_Sources inputSource);

六、动作集(Action Sets)

动作通过动作集进行逻辑上的分组,以方便进行组织和管理。在Unity中对应的类为SteamVR_ActionSet。在不同的场景或应用程序之间可以切换使用不同的动作集,比如,应用程序中有一个场景是在地球上拾取并投掷物体,而另一个场景则是在太空中飞行,那么这两个场景可以使用不同的动作集。同时,当针对新设备进行交互适配时,开发者只需对动作进行配置,而不必修改项目代码。比如,使用 Vive 控制器时,定义了一个Fire动作,当需要支持 Rift Touch 时,只需通过配置Touch控制器上符合 Fire 动作的键值即可。

SteamVR插件默认包含了三套动作集default、platformer、buggy,开发者也可以在SteamVR Input窗口中自行添加或删除动作集。

使用组件SteamVR_ActivateActionSetOnLoad可以在场景中自动激活和停用指定的动作集。对应激活和停用的方法是在Start()和OnDestroy()中实现。

七、SteamVR Input 窗口

在Actions栏的右下角,可以点击加减号按钮添加或删除动作。每个动作具有名称(Name)、类型(Type)、本地化字符串(localized String)等字段。其中,类型对应上节介绍的动作类型;本地化字符串是面向用户进行绑定的动作名称。

当点击Save and Generate按钮后,插件将为动作以及动作集生成可编程访问的对象类,将它们放置在项目的SteamVR_input目录下。

八、测试动作

选择 Window > SteamVR Input Live View 命令,即可打开一个测试输入窗口。运行程序,此时该窗口将实时展示所有动作集合的状态。

九、如何获取动作的值

using UnityEngine;
using Valve.VR;

public class TestAction : MonoBehaviour {

    void Start()
    {
        SteamVR_Actions.default_GrabGrip.onStateDown += Default_GrabGrip_onStateDown;
    }
    private void Default_GrabGrip_onStateDown(SteamVR_Action_Boolean fromAction,SteamVR_Input_Sources fromSource)
    {
        Debug.Log(fromAction.activeDevice);
        Debug.Log("down");
    }

    void Update()
    {
        if (SteamVR_Actions.default_GrabGrip.GetStateDown(SteamVR_Input_Sources.LeftHand))
        {
            Debug.Log("000down");
        }
        if (SteamVR_Actions.default_GrabGrip.stateDown)
        {
            if (SteamVR_Actions.default_GrabGrip.activeDevice == SteamVR_Input_Sources.LeftHand)
                Debug.Log("111down");
        }
    }
}

十、获取Vector1的值

using UnityEngine;
using Valve.VR;

public class TestAction : MonoBehaviour {

    void Start()
    {
        SteamVR_Actions._default.Squeeze.onAxis += Squeeze_onAxis;
    }

    private void Squeeze_onAxis(SteamVR_Action_Single fromAction, SteamVR_Input_Sources fromSource, float newAxis, float newDelta)
    {
        Debug.Log("newAxis" + newAxis + " newDelta" + newDelta);
    }

    void Update()
    {
        Debug.Log(SteamVR_Actions._default.Squeeze.axis);
        Debug.Log(SteamVR_Actions._default.Squeeze.GetAxis(SteamVR_Input_Sources.LeftHand));
    }
}

十一、获取Pose的值

using UnityEngine;
using Valve.VR;

public class TestAction : MonoBehaviour {

    void Update()
    {
        if (SteamVR_Actions._default.Pose.activeDevice == SteamVR_Input_Sources.LeftHand)
            Debug.Log(SteamVR_Actions._default.Pose.localPosition + " " + SteamVR_Actions._default.Pose.localRotation);

        Debug.Log(SteamVR_Actions._default.Pose.GetLocalPosition(SteamVR_Input_Sources.LeftHand));
    }
}

十二、获取Vector2的值

十三、手柄震动

using UnityEngine;
using Valve.VR;

public class TestAction : MonoBehaviour {

    void Start()
    {
        SteamVR_Actions.default_GrabGrip.onStateDown += Default_GrabGrip_onStateDown;
    }

    private void Default_GrabGrip_onStateDown(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
    {
        
    }

    void Update()
    {
        SteamVR_Actions._default.Haptic.Execute(0, 1.5f, 100, 0.5f,SteamVR_Input_Sources.LeftHand);
        SteamVR_Actions._default.Haptic.Execute(0, 1.5f, 100, 0.5f,SteamVR_Input_Sources.RightHand);
    }
}

十四、关于使用SteamVR打开动作绑定界面

鼠标点击“设置”——“控制器”——“管理控制器按键设置”——选中要修改的项目——“自定义”——“编辑此按键设置”

ps:在场景SteamVR_ShowTrackingReference中,给[CameraRig]添加脚本Steam VR_Tracking Reference Manager,可实现:虚拟环境中显示出定位器的模型。

十五、SteamVR_LaserPointer场景

(1)脚本SteamVR_LaserPointer参数:

Interact With UI:指定动作(搭配按键)设置;

Active:是否激活;

Color:默认下的射线颜色;

Thickness:射线的粗细;

Click Color:按下按键后的射线颜色;

(2)给Controller(left)添加PointerTest.cs,功能:测试左右手柄、及射线射中的物体名称;

using UnityEngine;
using Valve.VR.Extras;

public class PointerTest : MonoBehaviour {

	// Use this for initialization
	void Start () {
        GetComponent<SteamVR_LaserPointer>().PointerIn += PointerTest_PointerIn;
        GetComponent<SteamVR_LaserPointer>().PointerOut += PointerTest_PointerOut;
        GetComponent<SteamVR_LaserPointer>().PointerClick += PointerTest_PointerClick;
    }

    private void PointerTest_PointerClick(object sender, PointerEventArgs e)
    {
        Debug.Log(e.target);
        Debug.Log(e.fromInputSource);
    }

    private void PointerTest_PointerOut(object sender, PointerEventArgs e)
    {
        Debug.Log(e.target);
        Debug.Log(e.fromInputSource);
    }

    private void PointerTest_PointerIn(object sender, PointerEventArgs e)
    {
        Debug.Log(e.target);
        Debug.Log(e.fromInputSource);
    }
}

(3)射线和UI交互:

创建画布Canvas,添加按钮Button,给Button添加Box Collider

using UnityEngine;
using Valve.VR.Extras;
using UnityEngine.UI;


public class PointerTest : MonoBehaviour {
	void Start () {
        GetComponent<SteamVR_LaserPointer>().PointerIn += PointerTest_PointerIn;
        GetComponent<SteamVR_LaserPointer>().PointerOut += PointerTest_PointerOut;
        GetComponent<SteamVR_LaserPointer>().PointerClick += PointerTest_PointerClick;
    }

    private void PointerTest_PointerClick(object sender, PointerEventArgs e)
    {
        if (e.target.GetComponent<Button>() != null)
        {
            e.target.GetComponent<Image>().color = Color.green;
        }
    }

    private void PointerTest_PointerOut(object sender, PointerEventArgs e)
    {
        if (e.target.GetComponent<Button>() != null)
        {
            e.target.GetComponent<Image>().color = Color.white;
        }
    }

    private void PointerTest_PointerIn(object sender, PointerEventArgs e)
    {
        if(e.target.GetComponent<Button>()!=null)
        {
            e.target.GetComponent<Image>().color = Color.red;
        }
    }
}

十六、Interaction_Example场景

1.TeleportPoint:可移动的点

2.TeleportArea:可移动的区域

脚本Teleport Area.cs的参数:

(1)Locked:锁住/解锁;

(2)Marker Active:默认状态下,是否可见;

3.SteamVR_Fade:镜头渐隐渐现

将Steam VR_Fade脚本拖拽到[CameraRig]下的Camera上,其次,创建CameraFade.cs脚本挂载到[CameraRig]上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;

public class CameraFade : MonoBehaviour {

	void Update () {
		if(SteamVR_Actions._default.InteractUI.GetStateDown(SteamVR_Input_Sources.LeftHand)
            ||SteamVR_Actions._default.InteractUI.GetStateDown(SteamVR_Input_Sources.RightHand))
        {
            SteamVR_Fade.Start(Color.black, 1f);
            StartCoroutine("Delay");
        }
	}
    IEnumerator Delay()
    {
        yield return new WaitForSeconds(1f);
        SteamVR_Fade.Start(Color.clear, 1f);
    }
}

4.分析手部模型Skeleton

略。。。(以后用到了再补上剩下的)

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林枫依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值