The Lab交互系统
第一部分:自己创建一个简易交互雏形。
1.创建一个新的场景
2.删除场景中的主摄像机
3.将预制体目录/core/prefabs中的“Player”拖放到场景中,这个预制自带摄像机组件和手柄组件,并且已经关联号了SteamVR所必需的的脚本
4.运行你就能从头盔里看到场景内容,手柄也能被追踪到。
5.添加“Interactable”组件到场景中任意物体上,所有挂在此组件的物体将开始自动接收来自手柄的信息。(详细可以查看/Samples/Scripts/InteractableExample.cs脚本)
6.本系统内已经包含了一些常用的交互类,比如物件可抛性(Throwable)。添加这个组件到你的物件上你就可以让关联的物件可以被捡起或者被扔掉。
关于传送
7.从Teleport/Prefabs目录添加Teleporting预制体到你的场景中,这样你就可以设置传送功能。
8.从Teleport/Prefabs目录 添加TeleportPoint预制体到你的场景中,这个点就是限制你可以传送的点。
9.你也可以添加TeleportArea组件(其实就是脚本啦)到任意物体上,这样就可以允许你传送到任意带collider的物体处。
第二部分:核心功能讲解
1.Core 交互系统的核心,主要包含Player,Hand和Interactable这几个核心类,在Player的预制体中已经集成。
2.交互系统的工作原理是通过将消息发送到任何与手交互的对象上,然后这些对象对消息进行反应,并且可以将自己附加到任意想要的手柄上。
3.想要让任意物体接收来自手柄的交互信息,只需添加Interactable脚本到目标对象上。当手柄悬停在对象上时,即可做出反馈。
4.同样交互系统包含一些常用的交互比如拾取丢弃(Throwable)或者线性驱动(LinearDrive)。
5.palyer预制体同样会创建一个输入模块(InputModule),允许模拟鼠标操作,从而实现与UGUI的交互。
6.交互系统还包括一个fallback模式,允许第一人称相机控制使用键盘和鼠标操作,让鼠标模拟玩家的手。这种模式在无头盔的开发环境下是十分有用的。
Player类:
1.玩家类是一个单利,这将表明场景中只允许一个Player。
2.玩家类主要负责追踪手柄和头盔。
3.只要不为空,可以通过全局访问Player类。
4.VR模式和2D fallback模式也在此类中
5.访问Player类无需判断是否有头盔后者是否使用键鼠输入。
6.2D fallback虽然很有用,但是也有其局限性,我们主要使用它来做一些只需要单手的简单Trigger测试。这对于无头盔开发的团队成员来说非常实用。
Player类也包含了一些实用的属性:
hmdTransform:这个将总是返回当前摄像机的transfrom,这里可以是vr头盔或者是2D fallback模式的摄像机。
feetpositionGuess:这个属性将猜测Player的脚的位置相对于头盔位置,当然这个数据也不是绝对准确,具体取决于Player的站位。
bodyDirectionGuess:身体朝向,这个类似于feetpositionGuess,取决于Player的站位。
Note:
1.Player类可以在Editor中设置使用Icon来显示手和脚,但在Unity中这些图标必须在特定的文件夹内才能正常工作。在Core/Icons目录中已经提供了这些图标,将它们移动到名为“Gizmos”的目录中(需放在项目根目录)才能正常工作。
2.fallback模式在开发中十分有用,但是你可不希望你的发布版本也带这样的功能,所以这里有两种方式来禁用它:
1.在Player身上去掉“Allow Toggle To 2D”的勾选。
2.在PlayerSeetings中添加“HIDE_DEBUG_UI”到脚本定义符列表中,这将在发布版本中禁用2D debug视图但能再Editor(编辑模式)中使用。
Hand类
1.Hand类是整个交互系统中任务最重的。
2.此类检测可交互物件的悬停并且基于当前状态发送信息给它们。
3.一只手柄一次跟一个物件交互,并且同一时间只能一个手柄对应交互一个物件。
4.物件可以被附加在手柄上也可以被分离,只有一个物件会成为聚焦物件,但多个对象可以同时附加到手柄上。
5.一旦物件从手柄上分离(detached),前一个附加的对象(如果它还附着在手柄上)将成为新的聚焦对象。
6.没有任何附加物件时,显示手柄模型。
7.附加的对象可以设置“AttachmentFlags”标志位来决定手柄和对象被附加的行为。
8.手柄可以从悬停物体的具体情况来锁定。
以下为手柄发送给物件的交互信息:
OnHandoverBegin:当手柄接触到物体是发送此信息(事件触发,一帧);
HandHoverUpdate:悬停的时候每帧调用
OnHandHoverEnd:悬停结束时调用(类似OnTriggerExit,一帧)
OnAttachedToHand:附加到手柄上时调用
HandAttachedUpdate:附加到手柄上时每帧调用
OnDetachedFromHand:从手柄上分离时调用(一帧)
OnHandFocusLost:当其新物件附加时手柄失焦时调用。
OnHandFocusAcquired:当附加的物体获得焦点时调用,因为之前的物体已经从手柄上分离。
以下消息针对手柄的子物体:
OnHandInitialized:在获取SteamVR跟踪控制器关联的设备ID初始化后调用
OnParentHandHoverBegin:同上
OnParentHandHoverEnd;同上
OnParentHandInputFocusAcquired:游戏窗口获取输入焦点时
OnParentHandInputFocusLost:游戏窗口拾取输入焦点时
以下成员处理附加和分离:
AttachObject:使用传入的“AttachmentFlags”值来附加物件
DetachObject:从手柄上分离对象,并且可以选择将它还原到其原始父物体。
currentAttachedObject:返回为当前手柄上聚焦的物体
Hand类也有一些实用的属性和函数可用于自定义:
OtherHand:Player的另外一个手柄,这对于需要双手交互的操作时十分实用,比如弓箭
HoverSphereTransformandRadius:自定义手柄悬停范围(球形碰撞体的半径)
HoverLayerMask:设置手柄悬停交互的层
HoverUpdateInterval:悬停检测的频率(间隔)取决于游戏需求
HoverLock/Unlock:用来使手柄只能悬停在一个特定的物体上。传空值会使手柄不悬停任何物体当悬停为锁定时。这种技术通常用于传送激活时不让手柄处于悬停物体状态。
GetStandardInteractionButton/Up/Down:这个用于检测手柄的Trigger键的状态。这对于fallback模式十分实用,判断鼠标左键来关联此操作。
GuessCurrentHandType:这个主要是使用了SteamVR的函数来确定手柄的左右手。
GetAttachmentTransform:物件可以使用手柄上的“attachment transforms”来指出对齐到手柄的哪个点上。这些都被命名为手柄的子物体。在Player的预制体中包含了一个“Attach_ControllerTip”作为样例。
Interactable
Interactable 类有更多的标识符,它标识物件为手柄的交互对象。
任何带此组件的物件都将受到来自收到来自手柄的相关信息。
只需要使用这三个组件,你就可以创建一个包含更多不同又复杂操作的物体。
可以通过本交互系统已提供的一些基础组件来组合创造更加复杂的交互物体。
Throwable
这是最基础的交互组件之一
Player 可以当悬停并按下trigger时拾取带此组件(脚本)的物件。
当trigger键按下时物件附加到手柄上并且被手柄持有。
当trigger键释放时手柄将物件传速度并且抛出物体(分离)。
这个可以让你快速创建拾取和抛物功能。
LinearDrive
线性驱动
手柄的开始点到结束点之间可以关联物件的线性移动映射
物件的当前位置信息设置为LinearMapping。
CircularDrive
手柄的圆形运动映射物体的移动。
物体当前位置信息设置为LinearMapping(线性映射)
LinearMapping
线性映射
一个用于设置LinearDrive或CircularDrive的数字
映射可以让手柄实现更加复杂的交互行为
弓箭的例子就是让铉使用线性映射来实现弓箭拉伸时的动画效果。
映射使用了下列的类的一些属性:
LinearAnimation
LinearAnimator
LinearBlendShape
LinearDisplacement
HaticRack
VelocityEstimator(速度估值)
这个类用于估算物体在改变其位置时的速度和加速度;
通常情况下你是可以得到比较准确的获取到手柄的速度和加速度的,当然使用2D fallback模式的话当我没说。
IgnoreHovering
如果你想让某个物体忽略悬停检测,那么就讲这个组件挂载在物件或者某个特定的碰撞体上即可。
UIElement
添加这个组件到已有的UI上即可实现交互。
此组件将自动生成基于手柄交互的鼠标悬停和点击交互并且通过Unity Event System来实现最终的UI交互。
另外当单击一个UI元素时此组件也会生成一个OnHandClick事件传入手柄
本文为优三帝原创翻译,转载请注明出处,谢谢。