VRTK这个工具包提供了许多unity引擎中VR常用的功能,诸如(但不局限于):
用常用别名封装的控制器按钮事件
控制器世界光标指针(eg.镭射光标steamVR_LaserPointer)
玩家传送机制
用控制器抓取/握住游戏对象
用控制器和游戏对象交互
把游戏对象转化为可交互的UI元素
VRTK工具包项目拆分:
预设、脚本、案例
001-CameraRig_VR_PlayArea
展示[CameraRig]预设用法的简单场景,实际上就是对VR_PlayArea的简单设置。
002-Controller_Eventsduiying
还是001的场景,不同的是它控制器的事件进行了封装,便于在使用时进行调用,同时还在该事件触发时打印到控制台窗口。一旦触发对应的控制器事件就会在Console窗口显示。
脚本VRTK_ControllerEvents:(为我们提供控制器事件,即发出对应的事件)负责处理游戏控制器发出的事件,所以绑定在每一个控制器对象上,这样才能实时进行手柄按钮事件的监听(系统按钮除外:因为它是专门为Steam平台菜单预留的按钮,无法被重写)。
当一个控制器按钮被按下的时候,脚本会发送一个事件来表明这个按钮已经被按下了,这样做的好处是允许其他脚本在无须实现任何控制器逻辑的情况下就能监听这个事件,这就是所谓的解耦。
Trigger_Hairline:扳机微扣
Trigger_Touch:扳机触摸
Trigger_Press:扳机按下
Trigger_Click:扳机单击
Grip:手柄按钮
Touchpad_Touch:触摸板触摸
Touchpad_Press:触摸板按下
Application_Menu:应用菜单
Pointer Toggle Button:用来开关镭射光标的按钮,默认触摸板按下
Pointer Set Button:用来设置目的地标志的按钮,默认触摸板按下
Grab Toggle Button:用来抓取游戏对象的按钮,默认为手柄按钮
Use Toggle Button:设置使用游戏对象按钮,默认为扳机单击。
UI Click Button:用来点击UI元素按钮,默认为扳机单击。
Menu Toggle Button:用来调出游戏菜单的按钮,默认为应用菜单
Axis Fidelity:轴发生改变时的保真值,默认为1 。任何大于2的数值将有可能给出过于敏感的结果
003-Controller_SimplePointer
VRTK_SimplePointer:继承自VRTK_WorldPointer,又接着继承VRTK_DestinationMarker,继承MonoBehaviour。
在按下触摸板的时候从控制器上发射一条镭射光线,在碰撞到其他对象的时候会有一个光标指针,这个光标事件同样会打印到控制台窗口。()从控制器前端发射一条射线,射线指向的游戏对象就是我们选中的对象,然后用其他按钮来触发一些操作。
默认扳机键开关,要在VRTK_ControllerEvents里的pointer Toggle Button来改,因为整个事件都是通过该脚本来触发的,SimplePointer只是对事件进行监听。
Enable Teleport:光标指针获取新的目的地时能否传送过去。
抽象类:我们在写某个功能的时候,为了让这个功能可以很方便地重写和扩展,保持对象的一致性和方法的稳定性,就有了抽象类。
抽象层如何派生具象类的?
指针的原理其实很简单,标记一个终点,然后从原点发出一条射线,去获取碰撞到的点。原点就是获取当前的位置,这个很简单,所以指针的脚本主要都是在做终点标记的事情,中途无非是渲染光线懂得过程,所以抽象类就是标记重点VRTK_DestinationMarker.
004-CameraRig_VR_BasicTeleport
在003的基础上新增了简单版本的传送功能。
VRTK_Basic Teleport:按下触摸板发射镭射光线,松开触摸板时就会传送到光标所在的位置。
梳理一下流程:监听控制器事件——指针射线——重点标记——验证是否为有效传送点+传送(就是把CameraRig的位置设置为目标传送点的位置)
005-Controller_BasicObjectGrabbing
控制器触摸场景中物体时,物体高亮,扣动扳机即可抓起该物体,同时你可以做一个扔出去的动作,可以给该物体一个加速度,再松开扳机,即可把对象扔出去。
互动对象上再添加VRTK_Interactable脚本组件。
抓取逻辑:1,控制释放事件后立即执行器上的四个脚本组件
VRTK_Controller Events:(为我们提供控制器事件,即发出对应的事件)
VRTK_Controller Actions:控制器动作
VRTK_Interact Touch:触摸,触摸时可以配置是否隐藏控制器以及全局高亮颜色
VRTK_Interact Grab:抓取
2,对控制器按钮事件进行监听,监听到抓取和释放
006-Controller_UsingADoor
实现开关门功能
在抓取的四个脚本添加之后,又添加了VRTK_Interact Use(按下控制器上默认的扳机键来使用一个对象,释放该按钮停止使用该对象。).
在使用VRTK_Interact Use的前提是:建立在触摸和抓取之上,需要控制器事件和动作的支持。
在与可交互对象产生交互时,对象上往往需要一个脚本组件,该组件既可以使VRTK_Interacable Onject,也可以是继承于该类的子类。Openable_Door就是VRTK_Interacable Onject的子类。
也可以开窗户,开柜子,开闸等,只需要调整详细的角度即可。
007-CameraRig_HeightAdjustTeleport
展示了适应高度的传送机制,再有高低梯度的场景中,玩家应该拥有攀爬的能力,和现实中一样。同时,当脚下踏空的时候,也应该会掉落到低处,知道触地在实体上为止。
核心脚本:VRTK_Height Adjust Teleport
继承自VRTK_Basic Teleport,允许基于传送点事都在其他对象上来变更[CameraRig]的Y位置,和VRTK_Basic Teleport一样,脚本组件必须挂载在[CameraRig]上,且必须要World Pointer(世界指针)即可。
008-Controller_UsingAGrabbedObject
展示了抓取之后再使用对象的功能
场景中极简易的枪按下两个手柄按钮抓取后,再按扳机开火。
Gun是从VRTK_InteractableObject派生出的脚本组件是比较简单的可交互对象的应用。
上图Whirlygig也是继承自VRTK_InteractableObject,使盒子上的胶囊体旋转起来。
009-Controller_BezierPointer
003+007场景。来建立在适应高度传送的基础上,在光标指针上做了优化,使镭射光线呈贝赛尔曲线状,类似于抛物线。优点:使玩家可以传送到实现不可及或者有障碍的地方,例如围墙和高台。
这里贝塞尔光标指针取代简单光标指针,使传送的目标点更灵活。
VRTK_BasicPointer 继承自VRTK_WorldPointer.
贝塞尔指针会从控制器的末端发射一条曲线到任何高度的地表,这比SimpleLaserPointer有用的多,因为镭射指针会被障碍物挡住,而贝塞尔指针的光线是弯曲的,可以跨越障碍物标记到后面的地面,或者穿越高低不平的地形。
010-CameraRig_TerrainTeleporting
在007的基础上加了地形Terrain,也可以传送。
011_CameraRig_HeadSetCollisionFading
防穿墙功能,穿墙就变黑(防患于未然)
就像客户进入样板间看房子,由于VR空间中用户的自由度是极高的,难免会把头伸到墙里。在游戏里就是一个很明显的BUG,比如在FPS里玩家可以通过穿墙的漏洞来获取敌人的位置,然而NPC敌人的子弹并不能穿墙,玩家可以在获取视野后快速消灭敌人。
核心脚本VRTK_Headset Collision Fade:
探测什么时候用户的VR头盔与其他游戏对象发生碰撞,并且在探测到碰撞的时候淡入屏幕到一个单色。这样是为了处理那些把头部放进游戏对象(例如墙体、门、柜子)中进行透视的情况,但我们并不希望玩家发现这样的穿帮。
头盔与游戏对象发生碰撞时发出HeadsetCollisionDetect事件,表示探测到头盔碰撞;停止碰撞是,发出HeadsetCollisionEnd事件。
012_Controller_PointerWithAreaCollision
009贝塞尔光标的优化版。当射线遇到障碍物时无法进行传送。
与当这个玩家区域与障碍物碰撞时会从绿色变成红色,或者当传送区域是玩家无法站立的地方也会变红,变红则无法传送。
实际上是游戏的一种保护机制,避免玩家传送到某些区域。
013_UsingAndGrabbingMultipleObjects
006开门+008简单手枪 的优化版
014_Controller_SnappingObjectsOnGrab
展示不同的抓取对其方式。
光剑和宝剑和两把绿色的枪:利用对齐把手。所谓的对齐把手是指可交互对象的一个子类,往往是一个空物体对象。但是这个把手决定了抓取时可交互对象的朝向,也就是说其位置和旋转会根据把手来匹配。
红色的枪:基本对齐,不精确且没有把手,抓取的时候会取其位置的中心点。
红和绿色枪:精确对齐,Precision Snap与控制器触摸对象时点挂钩,抓取的位置就是触摸的地方。
015_Controller_TouchpadAxisControl
用Pad操作小车的前进和后退。按下扳机小车跳跃,按下的越多小车就会跳的越高。
核心脚本:RC_Car_Controller
可以设计赛道,就像动画片《四驱赛车》,解锁关卡和剧情,利用金币购买赛车配件等。
016_Controller_HapticRumble
宝剑+震动
展示可粉碎的盒子和一把大宝剑。拾取宝剑挥舞攻击盒子,控制器会根据宝剑攻击力度适当震动,攻击力度足够大的时候可以击碎这些盒子。
继承自Interactable_Object(可交互对象)
当检测到碰撞时看力度够大吗,力量达到破碎临界值时就爆开。
当蓝色盒子上的剑和红色盒子撞击时,触发手柄震动
基本思路是剑的物体碰撞器侦测到碰撞时,获取手柄的运动速度,来决定震动的强度。
如下图,controllerAction和ControllerEvents对应的手柄身这两个脚本。
关键的震动方法是:有VRTK.ControllerAction.TriggerHapticPulse ( 震动强度, 震动持续时间,震动间隔时间)。
017_CameraRig_TouchpadWalking
011触摸板在场景中移动
触摸板移动功能:VRTK_Touchpad Walking,在玩家位置添加刚体和碰撞体,以免玩家穿墙或者穿过其他带碰撞的游戏物体。
018_CameraRig_FramesPerSecondCouter
帧率幕布预设:每秒刷新多少帧,在平常的PC游戏是60,手机游戏减半。VR理想帧率:120,目前能够达到:90.
019_Controller_InteractingWithPointer
通过指针光线来使用可交互对象:按下触摸板激活光线,瞄准可交互对象,再次按下扳机键完成交互。
020_CameraRig_MeshTeleporting
007适用于网格碰撞体
21
如何抓取,使用带关节的可交互对象
固定关节对象:立方体
弹力关节:拉取抽屉
旋转追踪机制:开门关门
角色关节:对于操作那些不同形状和多节点的对象更方便,可以通过拉取相关的部分来改变形状。
22
自定义贝塞尔曲线指针:自定义轨迹和光标
23
射箭游戏:可交互对象的扩展
24
007,通过脚本组件的类名ExcludeTeleport或者Tag名把一些特定的对象排除在传送地点之外。如果对象上有同名的脚本组件或标签,就作为传送的地点。
25
送展示几乎所有已知互动控制的设置以及如何对发出的事件进行响应。
VRTK_Simulator:WSAD控制移动
26
制让玩家在游戏开始的时候就抓取一个对象在手里,并且防止玩家丢弃该对象。
默认已抓取,强制触摸和企图抓取方法来实现自动抓取的。
27
传送的触发方法:触摸并使用地图上的对象把玩家传送到指定的地点,类似水晶球,而且水晶球里面还有一个场景预览。
28
按下触摸键,玩家区域与自己一起移动到目的地。
VRTK_RoomExtender
29
展示控制器和对象的提示信息展示方式。很多游戏中都会有一些提示信息,控制器上的往往是一些操作提示,而游戏对象上往往是一些游戏线索。
运行时,控制器和游戏对象上都会显示相应的提示信息,从而帮助玩家学会操作。
VRTK_Controller Tooltips
VRTK_Object Tooltips
30
展示控制器触摸板上的环形菜单,游戏设置:暂停、继续、保存(悬浮一个曲面窗口、出现在玩家手臂上、在控制器的任何位置)
031
把贝塞尔曲线指针放在头盔上,激活光线、和可交互对象的互动都是通过控制器来完成的,从头盔发射光线有凝视某个物体的感觉。
032
和在僵尸游戏中配置Ak有相似之处
033
传送到unity自带的导航组件navigation
034
在右控制器上的VRTK_UIPointer脚本组件使用一道简单的指针射线和UGUI产生交互,
在左控制器上控制的是头盔上发出的简单指针,通过凝视再与UGUI产生交互。
035
修改透明度和高亮
036
如何自定义混合指针
左控制器是简单指针
右控制器是贝塞尔曲线指针
037
可以攀爬