本文基于 SteamVR 插件的开发文档翻译并总结 SteamVR 开发过程中的基本用法。本文总结汇总了 SteamVR 插件文档的内容,对文档部分内容进行了删减。目前仅仅只是翻译并结合部分内容进行补充,部分内容可能存在纰漏,后续会结合开发过程逐步更新修改此文章的内容。
插件文档地址:https://valvesoftware.github.io/steamvr_unity_plugin/articles/intro.html
设备 | 版本 |
---|---|
Unity | 2019.1.2.f1 |
SteamVR Plugin | V2.7.3 |
HMD | HTC VIVE Pro 2.0 |
插件下载有很多方式,可以前往 Steam 平台下载,也可以在 Unity Asset Store 搜索 Steam VR 进行下载。
Steam:https://store.steampowered.com/app/250820/SteamVR/
Unity Asset Store:https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647
安装教程详情参考:https://blog.csdn.net/xiaofeiyu321/article/details/120163304?spm=1001.2014.3001.5501
在 Unity 中导入 Steam VR 插件,导入完成后可以在 Window 菜单栏中打开 Steam VR 的输入窗口。
单击确定复制默认的 “SteamVR Input JSON” 文件。 这些 actions(动作)和 binding(绑定)将帮助交互系统工作,并为您提供如何开始的示例。
在打开SteamVR Input 窗口的过程中,插件会检测项目中是否存在 actions.json 文件,该文件存储了项目中动作(Action)与动作集(Action Sets)的信息,在打开SteamVR Input窗口时会读取该文件。如果没有 actions.json,插件会建议使用默认提供的示例文件
点击 Yes 后,会生成默认的与输入有关的 json 配置文件:
插件会将示例文件 actions.json 以及一些当前主流控制器的按键绑定配置文件拷贝到项目中的 StreamingAssets/SteamVR 下,在之后程序运行时,也将从此文件夹中读取用户关于动作(action)的配置信息。
拷贝上述 Json 文件并打开窗口后,点击底部的 “保存并生成” 按钮。 这将保存您的操作并生成一些类来初始化它们,并使您可以在编辑器中和通过代码轻松访问它们。
在窗口中有四个 Action Sets(动作集)以及动作集包含的 Actions(动作),我们可以在面板中根据需求自定义动作集(添加自己的动作集或者删除原有动作集的内容)。
我们自定义完成动作的设置后,可以点击 Open binding UI 就可以对动作进行绑定。
当点击 Save and Generate 按钮后,插件将为动作以及动作集生成可编程访问的对象类,将它们放置在项目的 SteamVR_Input 目录下。
完成上述操作后,打开 “交互系统” 示例场景,我们可以在 Assets/SteamVR/InteractionSystem/Samples/Interaction_Example 找到示例场景。
然后连接头盔,控制器等设备,点击 Unity 的播放,开始探索 “交互系统” 的示例场景。
注:示例场景中包含很多常用的功能,在日后的开发过程中,可能需要实现类似示例场景中的功能。例如,利用射线实现 UI 交互、利用手柄抓握物体、传送等。可以多体验一下示例场景,学习相关功能的实现。
由于沉浸在虚拟现实中时您的整个视野都会被覆盖,因此拥有您所握持的控制器的虚拟表示会很有帮助。SteamVR 提供了一种简单的方法,不仅可以获取通用控制器模型,还可以获取具有单独驱动组件的模型。 因此,当您在现实生活中扣动控制器上的扳机时,您也可以在虚拟世界中看到它也在拉动。 这有助于提高可用性并有力地促进存在感。
交互系统和简单示例场景都有使用渲染模型的装备。 在 [Camera Rig] 预制件的 Simple Sample 场景中,您将找到Controller (left)和Controller (right)。 这些游戏对象上有一个SteamVR_Behaviour_Pose组件,用于设置变换的位置和旋转。
在这些对象下,您将看到名为Model的 GameObjects,其中包含我们的SteamVR_RenderModel组件。 它有几个成员:
开发人员通常希望将游戏对象附加到控制器上的特定点。 为此,我们在控制器的每个部分下放置了一个名为 “attach” 的游戏对象,该部分以相关部分为中心。 为便于访问,您可以访问SteamVR_RenderModel脚本并调用GetComponentTransform(string componentName),它将返回 \a Transform(不进行任何 GC 分配)。 此处的 componentName 参数区分大小写,因此请确保传入的组件名称与运行时在 Hierarchy 视图中显示的完全相同。
SteamVR_RenderModel组件需要与设置其索引的对象位于同一游戏对象上。 在[CameraRig]预制件中,这是由SteamVR_Behaviour_Pose脚本完成的。
SteamVR Unity 插件的核心是 action(动作)。 虚拟现实正在快速发展,我们需要我们的软件能够与硬件一起发展。 SteamVR 输入将代码的设备特定部分抽象化,因此您可以专注于用户的意图 - 他们的 action(动作)。 而不是编写代码来识别 “将 Trigger 按钮下拉 75% 的方式来抓取块”,您现在可以只关注最后一点, “抓住块”。 您仍然可以为 “抓取” 的含义配置默认值,但用户可以在标准界面中将其重新绑定到他们设定的偏好(首选项)。 当新的输入设备出现时,您的用户可以发布绑定以共享该设备,而无需更改代码。
Input System 与之前处理用户输入有显著的不同,使用 SteamVR Input System,开发人员可以在应用程序之外定义默认的动作并与按键进行绑定,而不需要将输入视为某一特定设备的特定按键。这样新的设备可以快速适配应用程序,无需更改代码。比如,当开发者检测玩家是否抓取某个物体的时候,不是检测 Vive 控制器的 Trigger 键或 Oculus Touch 控制器的 Grip 键是否被按下,而是检测预定义的 “Grab” 动作是否为 True 即可。作为开发者,可以在 SteamVR 中为 Grab 动作设置默认按键和阈值,当程序运行时,也可修改这些数值以满足玩家的个人偏好。基于这种机制,不光能够解决控制器碎片化的问题,也可以快速适配未来发布的设备。
action(动作):程序中定义的用户行为,例如:传送、左右转动等。我们可以将这些动作与不同设备手柄的按键进行绑定。
开发过程中,我们只需要定义好用户可执行的动作,使用不同设备的用户只需要在手柄设置面板中自定义动作与按键的绑定就可以使用我们开发的程序了。
也即不需要重新编写代码,只需在设置面板更改动作的绑定。
[核心]:关注动作而不是按键本身!因为不同设备按键不同,但对于应用只需知道动作而不用在意按键。这样就能使得开发者在编程中专注于用户的动作,而不是具体的控制器按键。
这种抽象输入的风格与许多其他公司正在考虑的类似。 大多数主要虚拟现实硬件公司的成员都加入了 Khronos,创建了仍在开发中的 OpenXR 标准。(OpenXR 是一套标准接口,它介于设备生产商与内容制作之间。)
SteamVR 将动作分为 6 种不同类型的输入和一种输出类型:
Boolean 类型的动作是 True 或 False 的值。 例如,Grab 是一个常见的动作,要么为真,要么为假。 要么打算抓取某物,要么不抓取,不存在中间状态。 对于 Vive Wand,这可能意味着将扳机扣动 75%,对于 Oculus Touch,这可能意味着将手柄扳机扣动 25%,对于 Knuckles,这可能是电容感应和力感应的某种组合。 但最终它分解为真值或假值。在 Unity 中对应类为SteamVR_Action_Boolean,通常用于按钮动作。
Single 类型的动作是从 0 到 1 的模拟值,类似于浮点型(float)。在这些场景中,您需要更多数据而不仅仅是真或假。 这些比您预期的要少。 如果之前您正在读取 0 到 1 的值,然后等待它达到某个点,即阈值,那么您可以使用布尔操作完成相同的操作,从而使您的最终用户更容易进行自定义。 单个动作的一个很好的例子是 SteamVR 交互系统中遥控车的油门。 您作为用户所采取的动作可能因您希望汽车行驶的速度而异。在 Unity 中对应类为SteamVR_Action_Single,常用于获取 Trigger 键的键程值。
Vector2 类型的动作是两个模拟值的组合,是二维数据。 一般在 VR 中,这类动作最好通过径向菜单或 2D 定位来表示。 在 SteamVR 交互系统中,我们有一个驾驶遥控车和游戏平台(platformer)类型角色的示例。 在 Vive Wand 上,它映射到触摸板,但在 Oculus Touch 和 Knuckles 上,它映射到操纵杆。 对于遥控车,我们使用 y 轴来确定向前或向后的方向,使用 x 轴来确定转弯。 使用游戏平台(platformer),我们将 x/y 输入映射到角色移动的方向和幅度。在 Unity 中对应类为SteamVR_Action_Vector2,与 Unity 或 C# 中的 Vector2 类型相似,常用于获取 Trackpad 上手指接触点坐标。
Vector3 类型的动作不常用,是三维数据,有 3 个数据成员。 在 SteamVR Home 中,这用于滚动,x、y 和 z 是要滚动的页面数量。在 Unity 中对应类为SteamVR_Action_Vector3。
Pose 类型的动作表示三维空间中位置和旋转,一般用于跟踪 VR 控制器。 用户可以通过在控制器上设置姿势代表的点来自定义这些绑定。 一些用户可能会发现稍微不同的跟踪位置或旋转对他们来说感觉更好。在 Unity 中对应类为SteamVR_Action_Pose,用于获取手柄控制器的运动数据。
Skeleton 类型的动作使用 SteamVR 骨骼输入来获得我们对握住 VR 控制器时手指方向的最佳估计。这种类型的动作能够获取用户在持握手柄控制器时的手指关节数据,通过返回数据,结合手部渲染模型,能够更加真实的呈现手部在虚拟世界的姿态,虽然不及像 LeapMotion 等设备获取手指输入那样精确,但是足以获得良好的沉浸感。在 Unity 中对应类为SteamVR_Action_Skeleton(提供用于呈现手部模型的骨骼数据,每个关节点的位置和旋转)。
Vibration 类型的动作用于触发 VR 设备上的触觉反馈。 这可以是控制器、背心,甚至是椅子。
创建动作后,您可以在自己的脚本中使用它们,也可以使用我们创建的用于处理一些常见任务的统一组件。 它们被命名为 SteamVR_Action_Boolean、SteamVR_Action_Single、SteamVR_Action_Vector2、SteamVR_Action_Vector3、SteamVR_Action_Pose和SteamVR_Action_Skeleton。 将它们拖到 GameObject 上以查看它们可以做什么。
我们可以在 C# 脚本中定义对应类型的动作(具体代码参照后面文件所示):
将脚本挂载到物体身上,在 Inspector 面板中可以给定义的动作进行赋值:
也可以通过代码直接获取动作,获取动作的方法有很多种(可以参照 SteamVR 插件的 API 文档),如下图所示:
//通过该动作的完整路径获取动作--/actions/[actionSet]/[direction]/[actionName]
//动作的路径参照上图--/actions/default/in/InteractUI
//T--期望返回的动作类型,actionName--动作的名字,caseSensitive--检索时是否区分大小写
public static T GetAction<T>(string actionName, bool caseSensitive = false)
public static SteamVR_Action_Single GetSingleAction(string actionName, bool caseSensitive = false)
赋值后运行程序,在 Inspector 面板中可以看到已经赋好的值:
创建动作之后,可以进行动作测试。打开 SteamVR Input Live View 窗口,可以看到动作的触发情况:
红色代表动作未绑定按键,绿色代表就是触发了的 action(动作):
//如果 action(state)当前值为 true,则返回 true--返回当前动作的状态,检测按键是否一直被按住
//传入 SteamVR_Input_Sources
public bool GetState(SteamVR_Input_Sources inputSource)
//如果 action 的值在最近的更新中已更改为 true(从 false),则返回 true--按下按键
//传入 SteamVR_Input_Sources
public bool GetStateDown(SteamVR_Input_Sources inputSource)
//如果 action 的值在最近的更新中已更改为 false(从 true),则返回 true--松开按键
//传入 SteamVR_Input_Sources
public bool GetStateUp(SteamVR_Input_Sources inputSource)
SteamVR_Input_Sources 输入源:方法传入参数类型:
代码示例:
private void Update()
{
if (Boolean_Action.GetState(SteamVR_Input_Sources.Any))
{
Debug.Log("正在按扳机键!");
}
}
private void Update()
{
if (Boolean_Action.GetStateDown(SteamVR_Input_Sources.RightHand))
{
Debug.Log("右手扳机键被按下!");
}
if (Boolean_Action.GetStateUp(SteamVR_Input_Sources.RightHand))
{
Debug.Log("右手扳机键被松开");
}
}
完整代码如下所示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
public class ActionDemo : MonoBehaviour
{
public SteamVR_Action_Boolean Boolean_Action;
public SteamVR_Action_Single Single_Action;
public SteamVR_Action_Vector2 Vector2_Action;
public SteamVR_Action_Vector3 Vector3_Action;
public SteamVR_Action_Pose Pose_Action;
public SteamVR_Action_Skeleton Skeleton_Action;
private void Start()
{
Boolean_Action = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("InteractUI");
Single_Action = SteamVR_Input.GetSingleAction("Squeeze");
}
private void Update()
{
//if (Boolean_Action.GetState(SteamVR_Input_Sources.Any))
//{
// Debug.Log("正在按扳机键!");
//}
if (Boolean_Action.GetStateDown(SteamVR_Input_Sources.RightHand))
{
Debug.Log("右手扳机键被按下!");
}
if (Boolean_Action.GetStateUp(SteamVR_Input_Sources.RightHand))
{
Debug.Log("右手扳机键被松开");
}
}
}
在开发过程中,我们经常需要根据项目需求定制化相应的动作集。新建动作集可以通过 SteamVR Input 面板进行设置:
通过点击 SteamVR Input 面板中 Action Sets 的 “+” 号我们可以新建一个动作集:
在新建的动作集下方的下拉菜单中,我们可以设置该动作集在动作绑定界面的形式:
通过 Actions 下的 “+” 号我们可以为新建的动作集添加动作:
其中,Type 也即我们上文提到的动作类型。面板中的 Required 用于设置该动作在动作绑定界面中的提示方式:
这几种提示方式在我们开发过程中,可以针对项目各个动作进行要求,以便用户更好地进行动作的绑定。面板中的 Localized String(本地化的字符串),用以设置该动作在绑定界面的显示文本。
动作集中的动作添加完毕后,点击 Save and generate,保存并生成。之后,我们就可以通过点击 Open binding UI 进入动作绑定界面:
在动作绑定界面,我们新建的动作集提示存在动作未绑定,我们需要对动作集中的动作进行绑定。提示文本即我们在前面设置的 Localized String。镜像模式即我们在创建动作集时下拉菜单里的 mirrored。
之后我们便可以根据我们动作的类型进行按键的绑定,选择不同的按键进行设置。绑定完成后需要点击设置位置下的 “√” 进行保存更改。
在 VR 中看到你的物理控制器很好,但人们真正想要的是能够看到他们的手。 随着 VR 控制器的进步,我们看到了截然不同的功能。 一些控制器只能按下按钮(无触摸),有些控制器甚至在半空中也能给出良好的手指估计,我们开始看到手套和相机具有完整的每个关节位置/旋转跟踪。 SteamVR Skeleton Input 为您提供了一个 API 来获取所有这些不同类型设备的每个关节数据。 对于数据较少的设备,我们根据按下的按钮估计手指位置,而对于更高级的控制器,数据只是通过。
我们有两个运动范围可供您获取骨骼数据。 如果您正在寻找精确到真实世界的数据,您可以使用WithController运动范围。 这意味着我们会在控制器允许的范围内尽可能地估计您的手指在现实世界中的位置。WithoutController为您提供从手指张开的扁平手到握成拳头的全方位范围。
With Controller | Without Controller |
---|---|
根据您使用此数据的用例,您可能希望获得相对于不同事物的位置和旋转。 默认情况下,我们获得相对于它们的父级的位置和旋转。 但是您也可以相对于模型获取它们。
对于某些事情,访问手指卷曲程度的概要可能更有用,而不是每个手指上 4 个关节的位置和旋转。 这些值的范围从 0 到 1,其中 1 表示完全卷曲。 您可以在skeletonAction.fingerCurls[]以数组的形式访问curl信息,或者在skeletonAction.indexCurl、skeletonAction.middleCurl、skeletonAction.RingCurl、skeletonAction.pinkyCurl和skeletonAction.thumbCurl中单独命名。
了解手指之间的间隙也是一个常用的信息。 为此,我们以与 Curls(弯曲)类似的方式提供数据。 从 0 到 1 的范围表示手指之间的间隙大小。skeletonAction.fingerSplays[]作为数组,或单独命名为skeletonAction.thumbIndexSplay、indexMiddleSplay、middleRingSplay和ringPinkySplay。
不同的控制器具有不同的能力来跟踪手指的各个关节。 在这里,我们提供了一个概览值,可以让您大致了解当前控制器的保真度级别。
骨骼行为(skeleton behaviour)是一个组件,它使 unity 中常见的Skeleton Input任务变得更容易。 通过设置skeletonAction和inputSource你可以让行为为你做很多工作。
有两种形式的骨骼行为(skeleton behaviour)有五个有用的事件。 您可以订阅 unity 事件或更传统的 C# 事件。 C# 事件的好处是大多数 IDE 会根据事件类型自动为您创建一个带有命名参数的函数。
Valve 发布 The Lab 后,我们从该项目中汲取了经验,并创建了一个交互系统,其他人可以在他们自己的项目中使用。 此系统已更新为使用 SteamVR 输入和新的 SteamVR 骨骼输入系统。 该系统可以作为如何使用这些新系统的示例。 它包括以下示例:
有了这些基本的构建块,就可以继续创建一些相当复杂的对象。 至于示例,可以查看 SteamVR/InteractionSystem/Samples/Scenes 中的 Interactions_Example 场景。
Samples/Scenes 文件夹中的示例场景 Interactions_Example 包括所有主要组件,是您熟悉系统的好地方。 该场景包含以下元素:
现在我们将更深入地了解交互系统中包含的一些基本组件。 该系统分为几个不同的部分:
交互系统的核心是 Player、Hand 和 Interactable 类。 提供的 Player 预制件为场景设置了 Player 对象和 SteamVR 相机。
Player 类就像一个单例对象,这意味着场景中应该只有一个 Player 对象。
除了跟踪手和 hmd(Head mounted display,头戴式显示器) 之外,Player 本身不会做太多事情。
它可以在整个项目中进行全局访问,交互系统的许多方面都假设 Player 对象始终存在于场景中。
它还可以跟踪您是处于 VR 模式还是 2D 后退模式。
通过 Player 类使用访问器允许其他组件在不知道是否使用 VR 头盔或鼠标/键盘的情况下同样运行。
2D 回退模式很有用,但也有其局限性。 我们主要使用这种模式来测试只需要一只手和触发按钮的非常简单的交互。 它主要在开发过程中很有用,因为并不是团队中的每个人都始终随身携带控制器上的 VR 头盔。
Player 还包括一些有用的属性:
在添加 Interactable 脚本的对象上添加下面的脚本,通过手柄的交互获取手柄与物体交互时的 SendMessage。这里仅对部分进行演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR.InteractionSystem;
public class HandEvent : MonoBehaviour
{
private void OnHandHoverBegin(Hand hand)
{
Debug.Log("当手刚开始悬停在对象上时发送-->" + hand.name);
}
private void HandHoverUpdate(Hand hand)
{
Debug.Log("发送手悬停在对象上的每一帧-->" + hand.name);
}
private void OnHandHoverEnd(Hand hand)
{
Debug.Log("当手停止悬停在对象上时发送-->" + hand.name);
}
}
总结:可以给场景中的物体添加 Interactable 脚本标明物体是可以交互的。添加脚本后,当手接近物体时,物体边缘黄色高亮,提示物体能够进行交互。
注意:Throwable 脚本需要配合刚体组件一起使用。当物体身上没有挂载刚体组件时,添加 Throwable 脚本时会自动帮物体挂载刚体组件
补充:Throwable 脚本一般与 Interactable 脚本一起使用,用来创建可交互的游戏物体
在示例场景中,我们可以通过 Throwing 处的示例了解 Throwable 脚本的使用:
其中,物体投掷时的速度估算模式可以在 Inspector 面板进行设置:
释放速度类型 | 详细 |
---|---|
Get From Hand | 从手部获取速度 |
Short Estimation | 在释放时,将基于前三帧估计速度 |
Advanced Estimation | 在释放时,将找到你投掷的峰值速度,并根据周围的三个帧估计速度 |
在 Throwable 脚本中,我们还可以设置物体抓取时是否穿过物体。通过设置我们可以在抓取物体时使得手以及物体无法穿透场景中的其他物体。
可以穿透 | 无法穿透 |
---|---|
我们可以在 Inspector 面板利用 AttachmentFlags 参数进行设置,相关参数对应左右如下图所示:
在开发过程中,我们根据需要对 AttachmentFlags 进行部分选择来达到我们要的交互效果。例如,实现按动一下扳机键拾取,再按动一下扳机键放下。
[注]:需要事先将 Teleporting 预制体拖拽至场景中!否则即使添加脚本也无法实现传送功能。针对 TeleportPoint 也是类似的,也需要事先将该预制体拖拽至场景中。
与SteamVR_Render_Model组件不同,交互系统中的这个Render_Model组件处理控制器模型和手部模型,并单独启用/禁用它们。
Skeleton Poser 系统有一个简单的目的:当拿起物理对象时,你在游戏中的手应该变形为拿着对象的姿势。 这些稳固的姿势可以直接在 Unity 编辑器中创作和调整,以便随着游戏的进行快速迭代。 您可以在姿势之上应用奇特的效果,例如附加的每指动画和动态抓握,以及多姿势混合。
该系统的价值来自于简化的工作流程。 姿势不是处理导入的动画和噩梦般的动画图,而是存储为紧凑的资源,动画会根据与您所持物体相关联的姿势自动应用。 这允许在较小的时间预算内进行更复杂的手部行为。
这些是这些工具的基本功能。它们优于 Unity 动画的地方在于,姿势是在场景视图中创建的,复杂的行为可以通过轻按几个开关堆叠起来。
要将手部姿势添加到游戏中的任何对象,只需向其中添加SteamVR_Skeleton_Poser
脚本即可。 Poser 脚本有两个部分,我们将在下面的内容中介绍这两部分。
SteamVR_Skeleton_Poser脚本旨在独立于SteamVR交互系统运行,并可添加到您自己的系统中,但 SteamVR 交互系统开箱即用,是快速试用的好方法。
SteamVR_Skeleton_Poses是包含特定手部姿势和一些每指动画信息的ScriptableObject。
可以通过SteamVR_Skeleton_Poser脚本及其方便的用户界面添加和修改多个姿势。 您可以为一个 Poser 添加任意数量的姿势,但您可能最多只需要几个。 使用姿势编辑器中的按钮,可以创建新姿势,可以在姿势之间复制姿势数据,可以镜像姿势数据,可以将姿势重置为各种基础,并且可以将场景视图中的骨架更改保存为 改变姿势。 您还可以通过手指移动下拉菜单添加每个手指的附加动画。 这让手指可以根据骨架输入移动,同时保持姿势的约束。 有几种类型的手指运动:
使用 Poser 的混合编辑器选项卡,您可以设置混合行为,以复杂的方式混合和堆叠多个姿势。 将混合编辑器视为动画控制器,将姿势视为动画。 您可以添加三种类型的混合行为:手动、模拟操作或布尔操作。 手动行为必须由代码驱动,只需简单调用:
Poser.SetBlendingBehaviourValue(string behaviourName, float value)
另一方面,模拟和布尔动作行为由选定的动作自动驱动。 平滑值将是应用于它们的平滑速度,0 表示无。 模拟动作不需要平滑,但推荐用于布尔驱动的行为,因为它们看起来会更平滑。
Poser 组件将自动与 SteamVR 交互系统一起工作。 您需要做的就是将 SteamVR_Skeleton_Poser 脚本添加到可交互的游戏对象中。 交互上有几个设置,您应该确保更改:
Interactable.HideHandOnAttach
。 如果你留下它,这会隐藏你美丽的姿势!Interactable.HideControllerOnAttach
。 这将确保您的控制器不会妨碍您的手部姿势。Throwable
脚本。SnapOnAttach、DetachFromOtherHand、VelocityMovement、TurnOffGravity
。 如前所述,SteamVR_Skeleton_Poser 脚本旨在独立于 SteamVR 交互系统运行。 如果您使用 SteamVR_Behaviour_Skeleton
脚本来为您的手设置动画,您可以通过调用 BlendToPoser()
告诉它混合到特定姿势器的输出。
如果您使用不同的解决方案来为您的骨骼设置动画,Poser 可以按照 SteamVR_Skeleton_PoseSnapshot
数据类的格式根据命令生成姿势,该数据类保存所有骨骼的对象偏移和位置/旋转。 调用 poser.GetBlendedPose
,传递 SteamVR_Behaviour_Skeleton
或SteamVR_Action_Skeleton
和 SteamVR_Input_Sources
手部标识符。 这将根据该特定姿势的各种行为和选项为您提供完全合成的姿势,您可以自由地将其应用于您的骨骼。
姿势编辑器用于创建和编辑姿势(Steamvr_Skeleton_Pose
),可以将其作为脚本对象保存到您的项目中,并用于该对象或游戏中的任何其他对象。
当您第一次将脚本添加到游戏对象上时,在 Inspector 面板会看到一个选项,可以从项目中选择一个姿势,或者创建一个新姿势。
点击创建(Create)后,Unity 会在 Cube 下生成相应的手部模型的克隆体(Clone):
要预览您正在创作的姿势,请单击 “左手” 和 “右手” 部分中的手形图标以在场景中打开和关闭预览。 这些预览骨骼在它们的变换中保存了您的所有修改,因此请记住不要禁用已经进行修改的 Hand,除非它们已使用 “Save Pose
” 按钮保存。
执行此操作时在场景中实例化的手是临时的,只要脚本正确跟踪它们,就会在游戏运行时销毁它们。 在应用于预制件之前禁用双手预览是一种很好的做法,因为预制件中的骨架是凌乱、大且不必要的。
当只启用一个姿势时,最容易编辑姿势,但要使此选项卡中的某些按钮起作用,您需要启用两只预览手。 如果按钮变灰,您可能需要启用一个或两个骨架来激活它。
如果您想修改骨骼的姿势,只需打开可交互对象下方的层次结构。 你可以看到已经添加了一个 vr 手套骨架,你可以进去编辑这些骨骼的变换来形成你的姿势。
如果你想做出不对称的姿势,比如说一个不对称的物体——你可以为右手和左手创作一个不同的姿势。 但是,对于简单或对称的对象,您可能希望双手具有相同的姿势,因此您可以使用 Copy x Pose to y hand 按钮将您所做的任何单手修改复制到另一只手上。 当姿势被复制时,手会自动镜像到你的对象上,并且通常会给出完美的结果。 小心此操作,因为它会永久覆盖另一只手的姿势。
修改完成后,点选 Show Left Preview,查看左右手的预览。
预览完成后,点击 Copy Right Pose To Left Hand,使得双手姿态一致。点击 Save Pose 保存修改。
记得将 Interactable 脚本下的 HIde Hand On Attach 取消勾选,勾选了则代表手抓握物体时隐藏手,如果不取消勾选,运行时看不到手部模型。我们可以根据不同物体定制其握持动作。
要向对象添加更多可用姿势,或创建新姿势,请点击顶部姿势列表旁边的小加号按钮。 您将看到创建了一个新选项卡,默认情况下未选择任何姿势,您可以再次从项目中选择一个姿势或创建一个新姿势。 添加 SteamVR_Skeleton_Poser 的姿势将成为稍后可用于混合的姿势。 除了标记为 (MAIN) 的第一个姿势之外,这些顺序无关紧要,被标记为(MAIN)的姿势将是基本姿势。
在每个手形图标下方,您可能已经注意到手指移动的所有选项。 这是用于附加动画,您希望骨骼系统的单个手指动画应用到您创建的姿势之上。 默认情况下,这将设置为静态,但还有其他三个选项。
混合编辑器用于创建更加复杂的行为,即在多个姿势之间混合。
点击底部的加号按钮来添加一个新的混合行为,默认情况下称为 new Behaviour。 您可以启用和禁用行为,它们有一个 Influence 滑块,如果您不想在运行时严格启用和禁用它们,您可以在其中关闭和打开它们并使用更多渐变(中间值)。
他们有一个目标姿势,默认情况下,他们将混合到主要姿势。 因为主要姿势是基础,所以这不会做任何事情。 相反,您需要将其设置为已添加到姿势编辑器列表中的次要姿势之一。
共有三种不同类型的混合行为:
Manual:如果您希望此混合由脚本控制或仅在此处使用此值滑块在 Inspector 中设置,您将使用什么。 | Analog:允许您将此混合行为权重映射到项目中的模拟操作之一。 平滑速度可让您对此进行一些平滑处理。 0 意味着没有平滑,任何高于零的都将是缓慢的,随着值的增加,平滑变得越来越快。 一个合适的值应该在 10 到 30 之间,尽管您可能根本不想要任何平滑,因为这是一个模拟动作。 | Boolean:这与模拟动作非常相似,不同之处在于它可以映射到项目中的布尔动作,例如按下按钮。 在这种行为类型中,平滑可能更重要一点,因为如果您没有任何平滑,它将立即跳转。 同样,建议使用 10 到 30 之间的值。 |
如果将混合行为的类型选择为后两种,我们可以为混合行为设置 Action。Analog Action类型对应 Action_single,Boolean Action类型对应 Action_bool。
我们可以添加多个行为,从而在 Blending Behaviour 设置实现不同 Action 绑定不同的手势。但需要注意的是,混合行为需要我们为物体设置多个 Pose。这里我们以示例场景中的 Squishy 物体为例,演示如何设置并绑定。
如上图所示,Squishy 有两个 Pose,如下所示:
其中示例场景中的 Blending Editor 中已经为副姿势设置了 Action 对应于我们手柄的扳机键,这里我们对另一个 Pose 添加 Pose。我们指定动作(Action)为 Grip,在手柄中我们设置了 Grip 动作对应于手柄的侧边键。
平滑速度对应于 Pose 切换的平滑程度,0 意味着没有平滑,瞬间切换。
(写完这部分才发现好像不这样设置也能实现这个效果,直接在示例场景中直接扳机键或者侧边键就行 o_0,不过操作没问题)
每个混合行为的最后一个选项是 Mask。 任何使用过 Unity 的人形动画系统的人都会发现这个 UI 非常熟悉,而那些没有使用过的人会发现它是不言自明的。 如果您不使用 Mask,则混合行为将应用于整只手。 如果您选择使用 Mask,那么您可以选择手的不同部分来应用混合。 绿色部分将应用混合行为,而灰色部分则不会。
通过 Mask 我们可以混合多个姿态,从而实现同一动作的部分混合使用,也可以实现不同动作的部分组合使用。我们使用正方体(Cube)为例,首先创建一个手部姿势(PoseA),之后我们复制 PoseA,对 PoseA 的食指进行编辑,得到 PoseB,两个动作仅仅食指姿势不一致。
我们为两个姿势设置相对应的 Behaviour,同时针对 PoseB 姿势的 Mask 进行设置,勾选 Use Mask 并只保留食指部分的 Pose:
其中 PoseA 对应扳机键,PoseB 对应侧边键,在扣动扳机拿起物体时,可以在按下侧边键可以看到食指动作的变化。
模拟和布尔行为会自动生成动画,但您必须通过代码手动修改。这是一个示例脚本,它将使用正弦波调制名为 “Example Behaviour” 的行为:
using UnityEngine;
using System.Collections;
using Valve.VR;
public class PoseModulator : MonoBehaviour
{
SteamVR_Skeleton_Poser poser;
private void Start()
{
poser = GetComponent<SteamVR_Skeleton_Poser>();
}
private void Update()
{
// 设置 blendingBehaviour 的混合值,在 Manual type 的行为中效果最好。
poser.SetBlendingBehaviourValue("Example Behaviour", Mathf.Sin(Time.time * 10) / 2 + 0.5f);
}
}
出于各种原因,许多游戏都以不同的规模制作。 重要的是您的播放器可能会被放大或缩小。 姿势在运行时以任何 Player 比例应用,这很好,但姿势创作工具默认以正常比例完成。 如果您制作的对象应该在更大的比例下可交互,这将是一个问题,因为您在处理姿势时获得的预览与您在游戏中看到的姿势不匹配。 为了解决这个问题,我们添加了一个属性 Preview Pose Scale,它允许您更改姿势编辑器的工作比例。
此值应设置为您的 Player 的任何比例。
从不同的预览比例保存的姿势将无法区分,它只是编辑器的助手,可以显示您的姿势从不同比例的手应用的样子。
时间 | 操作 |
---|---|
2021-9-2 | 初次整理完成 |
2021-9-3 | 更新了部分内容的排版,补充了快速开始、输入系统的部分内容 |
2021-9-4 | 补充整理了输入系统、骨骼姿态的部分内容 |
2021-9-7 | 补充了 SteamVR 插件安装教程 |
2021-9-15 | 补充了 Interaction System 部分内容 |
2021-9-18 | 补充了 Skeleton Poser 部分内容,添加了示例演示 |
文档经过 9 月来断断续续地整理汇总,已基本趋近完整,后续可能不会再这么密集地进行更新。在后续开发过程中,再逐步对其中部分内容进行修改删减,对部分不完善的章节进行完善。中秋将至,预祝中秋快乐 @_@!