赞
踩
无抓取手势(手和物体会穿模)
适合非实物的抓取,例如魔法球。
适用场景
在需要精准抓取手势或者固定某几个抓取手势时,可使用 Hand Grab。
可以在物体表面(准确来说是物体的碰撞体)上的任意位置进行抓取,抓取时手指会贴在物体表面上,可以用任意根手指进行抓取。
相比于 Hand Grab,抓取手势更自由。
在远距离通过射线抓取物体,可以将远处的物体抓取到手上,或者在远距离操控物体移动。
VR 中手势交互需要两个对象:
展开玩家物体 OVRCamreaRig,其子物体 OVRInteraction 是所有交互功能的父物体:
展开 OVRHands > LeftHand > HandInteractorsLeft,可看到左手的 Interactor 共有两个:
HandGrabAPI:检测 Hand Grab 是否选中或者取消选中可抓取物体。即,检测抓取动作是否发生。
HandWristPoint:控制在抓取时虚拟手部和现实手部在位置和旋转角度上的偏移。
GripPoint:Palm Grab 的探测范围。
调整 GripPoint 上的 HandWristOffset 脚本参数可以修改探测范围的位置和旋转角度。物体进入探测范围后触发抓取,会被吸到手上。
PinchPoint:Pinch Grab 的探测范围。
范围大小取决于 PinchPoint 子物体的 Collider 的碰撞体大小。
PinchArea:PinchPoint 的 HandPinchOffset 脚本默认引用 PinchArea , PinchArea 碰撞体的位置会影响 PinchPoint 探测范围的位置。
HandGrabVisual :连接 SyntheticHand ,在手部呈现出完整的抓取手势后固定手部姿态,让抓取手势不与物体穿模。
HandGrabGlow:控制抓取时手部的特效。
可抓取物体上需要添加 “Grabbable” 脚本,以实现在抓取物体的时候控制物体的位移、旋转和缩放。
可抓取物体下有一到多个 HandGrabInteractable 物体,即 Hand Grab 所需要的 Interactable 对象。
在示例场景 HandGrabExamples 中,Interactable 对象被统一存放在 Interactables 路径下。以 SimpleGrab2PalmGrab 为例,其子物体 HandGrabInteractable 挂载了交互脚本 “Hand Grab lnteractable”。
Supported Grab Type:抓取方式。
Pinch / Palm Grab Rules:抓取触发手指的规则。
Thumb、lndex、Middle、Ring、Max:大拇指、食指、中指、无名指、小指。
Unselect Mode:取消抓取的判定条件。
Hand Alignment(Unity 中单词拼写错误):决定虚拟手如何变化到对应的抓取手势。
[Optional] ScaIed Hand Grab Poses:为不同大小的手配置相应的抓取手势。
在运行程序时,如果当前 HandGrabInteractable 物体上没有挂载 “Move Towards Target Provider” 脚本,“Hand Grab lnteractable” 脚本会自动添加 “Move Towards Target Provider” 脚本,用于控制物体被抓取时朝向手部的移动。
如果想在程序运行前控制物体朝向手部的移动速度,可以在 HandGrabInteractable 物体上添加 “Move Towards Target Provider” 脚本,并设置其引用。
(1)Move From Target Provider
抓取时将手部吸附到物体上,而不是物体吸附到手上。
(2)Follow Target Provider
抓取时物体会跟随手部移动,具有阻尼效果。
(1)将 《2024-04-01 NO.3 Quest3 手势追踪与玩家角色配置》 文章中 SampleScene 场景下的 OVRCameraRig 进行 Prefab Unpack Completely,之后拖拽到 Assets > Prefabs 文件夹下。
(1)在 Package 中找到 HandGrabInteractor 预制体,将其拖拽为 SampleScene 场景中 MyOVRCameraRig > OVRInteraction > OVRHands > LeftHand > HandInteractorsLeft 的子物体。并对 RightHand 进行同样的操作。
(2)场景中展开 LeftHand 下的 HandGrabInteractor 对象,将其 Visuals 下的两个子对象 HandGrabVisual 和 HandGrabGlow 激活,并设置对应的引用参数。同样的操作应用于 RightHand(步骤中所有 Left 对象改为 Right)。
<--
OVRLeftHandSynthetic。<--
OVRLeftHandSynthetic > OVRLeftHandVisual。<--
OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。<--
OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。(3)找到 LeftHand > HandInteractorsLeft 物体上的 “Best Hover lnteractor Group” 脚本,将 HandInteractorsLeft 物体拖拽入 Interactors 列表中。同样的操作应用于 RightHand > HandInteractorsRight 物体(步骤中所有 Left 对象改为 Right)。
Interactors 列表存储不同种类的 Interactor 脚本。
Interactor Group 保证其列表下的所有 Interactor 在同一时刻只有一个进行交互,而其他 Interactor 暂时失活。
此处 Best Hover Interactor Group 是 Meta XR SDK 中 Interactor Group 的其中一种。其特性是:
保证优先级高的 Interactor 进入到 hover 状态,优先级低的 Interactor 会暂时失活。
默认情况下,越靠前的列表元素拥有越高的优先级。
(1)在场景中创建一个桌面(Cube,这里配置了红色材质),桌面上放一个立方体 Cube 用于抓取。
同时,给 Cube 添加 Rigidbody 和 Grabbable 组件,并将其 Box Collider 设置为 Trigger,取消勾选 Rigidbody 的 Use Gravity 选项。
最后,勾选 Grabbable 的 Transfer On Second Selection 选项,以实现左右手交替抓取。
(2)在 Project 中找到 HandGrabInteractable 预制体,将其拖拽为 Cube 的子物体。可以看见 HandGrabInteractable 自动寻找到了其父物体中的 Grabbable 和 Rigidbody。
到此,运行程序,可以实现双手抓取移动 Cube。
运行程序时,可以看到 Cube 物体上自动添加了 One Grab Free Transformer 脚本,并且被 Grabbable 脚本引用。
Grabbable 脚本通过 Transformer 来控制物体被抓取时的移动旋转和缩放。默认使用 One Grab Free Transformer 脚本(一只手控制)。
其他 One Grab Transformer:
取消勾选 Cube 挂载的 Grabbable 脚本的 Transfer On Second Selection 选项,并更换 One Grab Free Transformer 脚本为 Two Grab Free Transformer 脚本,即可使用双手操控物体。
若想实现单双手都可操控,则同时添加 One Grab Free Transformer 脚本即可。
(1)在 Cube 下方新建空子物体 Visuals,用于控制 Cube 的颜色显示。
(2)为 Cube 依次添加以下脚本:
Interactable Color Visual:控制物体在各种状态下显示的颜色。
需要设置:
<--
Material Property Block Editor 脚本。<--
Interactable Group View 脚本。Material Property Block Editor:关联物体材质。
需要设置:
<--
Cube 的 Mesh Renderer 组件。Interactable Group View:可交互物体组。
需要设置:
<--
HandGrabInteractable。 设置完成后,即可通过改变 Interactable Color Visual 中的 Color State 来更改物体对应状态的颜色。
到此,我们可以对 Cube 进行抓取、移动和旋转,但是没有录制抓取手势。
(1)取消 Cube 的 Box Collider 的 Trigger 选项,并勾选 Rigidbody 的 Use Gravity。此时,手部可以和 Cube 进行碰撞,手部碰撞体在 MyOVRCameraRig > TrackingSpace > LeftHandAnchor > OVRHandPrefab 下(运行状态下可见)。
这里运行时产生碰撞体是因为先前设置了 Enable Physics Capsules 选项。
(2)为 Cube 添加 Physics Grabbable 脚本,添加时会自动关联 Cube 上的 Rigidbody 和 Grabbable。
(3)将 Cube 上的 Physics Grabbable 脚本关联到 HandGrabInteractable 对象上。
(4)在 Project 中找到 HandVelocityCaIculator,将其拖拽为 LeftHand / RightHand 的子物体。
(5)关联对应的 LeftHand / RightHand。
(6)将 HandVelocityCaIculator 关联到 HandInteractorsLeft > HandGrabInteractor 和 HandInteractorsRight > HandGrabInteractor 对象上。
此时,即可完成 Cube 物理抛掷的效果。
如果在抛掷过程中有穿模现象,可以将 Cube 的 Rigidbody 的 Collision Detection 设置为 Continuous Dynamic,进行连续动态的碰撞检测,但性能消耗会更大。
录制抓取手势需要在 Unity 编辑器运行模式下进行,并且需要将头显和电脑进行串流(串流部分在 《2024-03-28 NO.1 Quest3 开发环境配置教程-CSDN博客》 中提及)。
(1)打开 HandGrabPoseTool 场景,添加待录制的物体 Cube(这里还添加了一个子物体 Cube)。并确保物体上挂载 Rigidbody 组件和 Grabbable 脚本,没有则手动添加。
这里将 BoxCollider 设置为 Trigger,取消勾选了 Rigidbody 的 Use Gravity 选项,并勾选了 Grabbable 脚本的 Transfer On Second Selection。
(2)运行 Unity,按下按钮,开始做抓取手势动作,3s 后将自动结束录制。若想要延长录制准备时间,可在前方点击按钮进行调整。注意,录制完成后不要急着退出运行模式。
(3)录制完成后,可以看见 Cube 下方多了 HandGrabInteractable 子物体。首先将 Cube 拖拽至 Assets > Prefabs 文件夹下成为预制体,再退出 Unity 运行模式。
(4)在 Unity 编辑模式下,删除场景中原有的 Cube,将刚创建的预制体拖入场景,开始进行手势微调。
点击 HandGrabInteractable > HandGrabPose 物体,找到其挂载的 Hand Grab Pose 脚本,调节其参数以达到想要的手势。
Fingers Freedom:手指灵活程度。
Joint Angles:关节角度。
改变值可旋转每个关节的角度,也可以在 Scene 窗口中直接旋转蓝色圆圈编辑调节。
微调完成后,失活 HandGrabPose 的子物体 Ghost-RightHand(Clone),即可取消显示录制手势。之后抓取物体时,手部会呈现刚录制好的姿势。
点击上方菜单 Oculus > Interaction > Hand Grab Pose Recorder,打开录制窗口。
(1)配置场景中想要录制的手,以及待录制物体的刚体组件。这里选择的是右手。
(2)运行 Unity,在做好手势后用鼠标点击 Record HandGrabPose 按钮即可完成录制。建议录制时将物体的 Collider 选择 Trigger,并取消勾选了 Rigidbody 的 Use Gravity。
由于录制时带着头显,不方便使用鼠标。因此可以配置相应的键盘按键(默认是空格),按下该键盘按键后即可完成录制。使用键盘按键来结束录制时,需要先将鼠标双击
Hand Grab Pose Recorder 录制窗口,以获取焦点。
注意,录制完成后不要急着退出运行模式。
(3)录制完成后,点击 Save To Collection 按钮保存录制结果,再退出 Unity 运行模式。
(4)在 Unity 编辑模式下点击 Load From Collection 按钮,即可获取刚录制的手势。
可以看到,Cube 下方添加了两个 HandGrabInteractable,且其中一个记录了手势。其上方没有手势的 HandGrabInteractable 是因为录制前 Cube 拥有一个 HandGrabInteractable 子物体,在读取结果时将其一并拷贝了进来,这里删除即可。
之后录制时,不需要先给物体配置 HandGrabInteractable,添加好 Rigidbody 后直接录制即可。
选中需要镜像手势的父物体 HandGrabInteractable,点击 Create Mirrored HandGrabInteractable 按钮,即可生成镜像手势。
调节 Scaled Hand Grab Poses 下方的 Scale 值,点击 Add HandGrabPose Key with Scale XXX 按钮后,即可生成对应缩放比例的手势。
(1)在 Project 窗口中找到 DistanceHandGrabInteractor 预制体,将其拖拽为 HandInteractorsLeft / HandInteractorsRight 的子物体。同时,将其挂载到 HandInteractorsLeft / HandInteractorsRight 的 Interactors 列表下。
(2)展开 DistanceHandGrabInteractor 的 Visuals 子物体,将其两个子物体激活。并进行如下关联(与 3.1.2 节 相同):
<--
OVRLeftHandSynthetic。<--
OVRLeftHandSynthetic > OVRLeftHandVisual。<--
OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。<--
OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。 同样的操作对 OVRRightHandSynthetic 再执行一遍(步骤中所有 Left 对象改为 Right)。
(3)将先前配置好的 HandVelocityCalculator 关联到 DistanceHandGrabInteractor 上。该步骤为可选,但需注意左右手对应配置。
参考 3.2.1 节 内容,创建一个 Cube,添加 Rigidbody 和 Grabbable 脚本,并将其设置为 Trigger,取消 Use Gravity。
之后,为该物体添加 Distance Hand Grab Interactable 脚本,添加时会自动关联 Cube 上的 Rigidbody 和 Grabbable。
此时运行 Unity,双手对准 Cube 握拳后,Cube 会被远距离抓到手上。这是因为 Cube 上 Interactable 脚本的 Supported Grab Types 和 RightHand 下 Interactor 的 Supported Grab Types 都是 Pinch。 如果不匹配,则不会被抓取。
(1)准备模型,这里使用两个 Cube 当成一把剑。其父子结构如下图。
给 Sword 添加 Rigidbody 和 Grabbable 组件,同时添加 Physics Grabbable 脚本。
Cube 和 Cube (1) 上带有 BoxCollider,且均设置为 Trigger。
(2)进行手势录制,并做一些微调。这里将所有手指都设置为 Locked。
(3)在生成的 HandGrabInteractable 物体上添加 Distance Hand Grab Interactable 脚本,并为其关联 Physics Grabbable 脚本。
对于 Hand Grab Interactable 脚本,其 Physics Grabbable 的引用在录制时被自动关联,因此这里不需要再重复关联。也可以手动检查确认一下。
(4)恢复物体的 Use Gravity,并且将 Collider 的 Trigger 选项取消。此时这把“剑”便拥有了远距离抓取和抛掷的功能。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。