VRTK使用心得(三):瞬移

本文节选自视频《HTC VIVE 交互开发实例教程》的第18课时。

在配置VRTK一篇中我们对瞬移做了初步的实现,但是作为一款优秀的工具集,VRTK还为我们提供了很多可以自行控制的功能,涉及到日常开发中经常遇到的问题,比如自定义射线的外观、让指定的物体不参与到瞬移中、自适应高度的瞬移(楼梯)等。

为什么在VR中使用瞬移?好好走路不行吗?

这个问题我们在《VRDC笔记——VR交互原型制作的50条最佳实践》中也涉及过这种交互原则。你可能在VR内容中习惯了使用瞬移,但是按照自然交互原则,理应是像现实一样自由行走才对,为什么需要使用瞬移呢?这主要是由当前硬件限制以及人的生理结构决定的。这需要从人的前庭系统说起。人眼获取信息,反馈给前庭系统,当眼睛与前庭系统不一致的时候,人会感到不舒服,比如当体验VR过山车游戏的时候,多数情况下会感觉到不适,我们的眼睛知道哪里加速、减速、坠落,但是前庭系统并没有相应的感受到加速、减速、坠落,于是就引起不适,这跟晕车晕船一样的道理。所以,在VR中的移动,尽量避免加速、减速,甚至是匀速。由于屏幕刷新率的问题,如果制作的VR内容帧率过低,则容易引起晕动症,这种感觉试一下Cardboard类型的眼镜就可以体会到,比如暴风魔镜等。

表现形式及原理

VR中的瞬移过程,是在体验者决定移动之前,通过手柄选择目标位置,选定之后,视野呈现短暂黑屏(时间相当于一次眨眼),过后将体验者位置设定为选定位置。
Unity VR中的瞬移,选择的过程基于碰撞体,即,默认情况下,有碰撞体的物体,都可以作为移动以后的目标点,故可以通过设定碰撞体的范围对可移动范围进行简单限制,比如,房间漫游中,可以将地面的碰撞体沿地面边界缩进一定的距离,来防止用户穿墙。关于更多防穿墙的体验优化,可参考《VRTK使用心得(六):优化用户体验——防穿墙及自动坠落》一节。

具体实现

  1. 我们假定已经将VRTK初始配置完毕,即保证LeftController和RightController挂载VRTK_Pointer指针脚本,并确定其Enable Teleport属性勾选。
  2. 如下图,在本场景以地面为瞬移范围,为其添加一个BoxCollider。


    图一
  3. 在VRTK配置结构下,添加一个空物体,可以命名为PlayArea,为其添加VRTK_BasicTeleport组件。


    图二

该组件的属性:

  1. Blink To Color:闪屏的颜色。前面说到黑屏,还可以设置任意颜色。
  2. Blink Transition Speed:闪屏持续时间,建议设置在1秒以内。
  3. Distance Blink Delay:数值在0-32之间,此参数用闪屏消失的延时,来体现瞬移过程的远近程度,新目标点与原目标点越远,闪屏褪去延时越长。
  4. Headset Position Compensation:头盔位置补偿。因为VIVE的特性,体验者是可以在小范围内移动的,所以,头盔与游玩区域(Play Area)会有一个相对位置,如果此选项被选中,新的位置会考虑头盔与游玩区域(Play Area)的相对位置,如果不选中,则只将游玩区域的中心位置设定到新的位置。可参考本组件的源代码片段如下:
newX = (headsetPositionCompensation ? (tipPosition.x - (headset.position.x - playArea.position.x)) : tipPosition.x);
newY = playArea.position.y;
newZ = (headsetPositionCompensation ? (tipPosition.z - (headset.position.z - playArea.position.z)) : tipPosition.z);
  1. Target List Policy: 一个限定参与瞬移的配置。前面我们说到,默认情况下,瞬移范围由碰撞体的范围来决定,Target List Policy则指定了一个更加灵活的规则,用来确定哪些物体是可以参与瞬移的,这个我们会在下篇进行说明。
  2. Nav Mesh Limit Distance: VRTK可以使用Nav Mesh来确定瞬移范围,注意还是需要保证有Collider,在Bake好Nav Mesh信息以后,此属性设定的值为Nav Mesh 边界以外多少米的范围可以参与瞬移。结合Nav Mesh进行瞬移的优点是可以将不想参与瞬移的物体,比如障碍物隔离在Nav Mesh以外。

另外两种瞬移:

在VR场景中移动,有时会遇到移动到一个相对高的位置,这时候使用基本的瞬移,只能是移动到与之前位置高度相同的位置,即Y坐标不变,这时候就容易出现移动到物体内部的情况,比如爬楼梯、爬山等,这时候就需要使用到一个能够自适应高度的瞬移脚本,叫VRTK_HeightAdjustTeleport组件,该组件能够实现在移动到一个相对高度的位置,同时改变体验者PlayArea的高度。使用方法与Basic Teleport相同,挂载到PlayArea上即可。如下图:


图三

通过上图观察,该组件大部分属性与VRTK_BasicTeleport相同,通过源代码也可得到验证,它继承了VRTK_BasicTeleport类,实现自适应高度的过程,是添加了一个GetTeleportY的函数,代码片段如下:

            float newY = playArea.position.y;
            float heightOffset = 0.1f;
            //Check to see if the tip is on top of an object
            Vector3 rayStartPositionOffset = Vector3.up * heightOffset;
            Ray ray = new Ray(tipPosition + rayStartPositionOffset, -playArea.up);
            RaycastHit rayCollidedWith;
#pragma warning disable 0618
            if (target != null && VRTK_CustomRaycast.Raycast(customRaycast, ray, out rayCollidedWith, layersToIgnore, Mathf.Infinity, QueryTriggerInteraction.Ignore))
#pragma warning restore 0618
            {
                newY = (tipPosition.y - rayCollidedWith.distance) + heightOffset;
            }
            return newY;

除了闪屏瞬移,还有一种瞬移形式,即,伴随着闪屏,体验者能够感受到移动的过程,但是这个过程极快。在VRTK中,使用的是VRTK_DashTeleport,同样,这个脚本继承了前面VRTK_HeightAdjustTeleport组件——能够实现基本瞬移,能够自适应高度,扩展的选项可以自定义这个过程的相关属性,比如时间、速度等。

图四

下篇中,我们将详细介绍VRTK限定瞬移区域的三种方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 角色控制是游戏设计中必不可少的一个设计环节,这一节我们讲一讲如何制作基本的角色运动控制交互逻辑。 因为是简单实例教...
    shimmery阅读 9,220评论 5 20
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,398评论 25 707
  • 九月初南京之行
    佛山飞戈阅读 135评论 0 0
  • 卖电子产品的声音 是黑夜的口舌 霓虹打算放大瞳孔 让属于无限的神秘 铺满脂粉与不安 远方不是地理名词 远方传递一种...
    孟小繁阅读 153评论 0 0
  • 独处的灵魂,忧伤的寂寞 请你告诉我,在你广阔的天地 会遇见吗? 过去,未来时光隧道里 行走,探索 无助、胆怯、忧伤...
    一抹清风醉红尘阅读 256评论 0 1