> 文档中心 > SteamVR 2.x 手柄拾取3D物体(13)

SteamVR 2.x 手柄拾取3D物体(13)

在实际项目过程中,触碰和拾取物体是最常用的功能之一,本章介绍手柄拾取物体的交互。

一、前期准备

新建场景,删除默认相机,将Player拖拽进入场景内
SteamVR 2.x 手柄拾取3D物体(13)
新建Plane,修改为Floor,上一个黑色材质球,Transform信息如下:
SteamVR 2.x 手柄拾取3D物体(13)
场景内添加CubeA,组件信息如下
SteamVR 2.x 手柄拾取3D物体(13)
除了添加Interactable组件之外,还需要添加Thrwoable组件,Rigidbody会自动添加,经过以上操作后,运行游戏测试,手柄进入CubeA后触发拾取动作(默认握柄键),CubeA就会被拾取起来,结束动作后CubeA会受到物理作用掉落,这里也可以将CubeA抛出,也会有简单的抛物线自由落体的物理效果。

二、Thrwoable组件参数解析

SteamVR 2.x 手柄拾取3D物体(13)

Attachment:抓取状态标记

SteamVR 2.x 手柄拾取3D物体(13)

  • Nothing:抓取时物体不会随着手柄移动
  • SnapOnAttach:抓取的瞬间,调整抓取对象位置,适应侯冰状态
  • DetachOthers:第二只手抓取时,原手不会自动松开
  • DetachFromOtherHand:第二只手抓取时,原手自动松开
  • ParentToHand:抓取时,对象作为手的子物体
  • VelociryMovement:抓取对象尝试移动到手的位置
  • TurnOnKinematic:抓取时开启动力学
  • TurnOffGravity:抓取时关闭重力
  • AllowSidegrade:对象可以从捏切换到握,降低意外脱手的可能
Attachment Offset:抓取偏移局部坐标点
Release Velocity Style:松开物体时力的来源
  • NoChange:无变化,物体自身刚体的力 GetFromHand:来自手的世界空间力
  • ShortEstimation:瞬时预估,根据最后时刻的力估计
  • AdvanceEstimation:高级预估,根据所受的力的最佳平均值来估计
Release Velocity Time Offset:当力的来源为手时,获取力的时间偏移量
Scale Release Velocity:松开力的缩放
Restore Orginal Parent:松开时回到原有父节点下

三、物体拾取的事件监听

在实际项目开发中,我们经常会有类似功能
1、拾取钥匙,门把手高亮,钥匙触碰门把手后,播放开门动画
2、拾取螺丝,安装位置高亮,触碰后安装到某个位置。
此时就要监听手柄拾取和松开,如:监听手柄拾取钥匙,通知门把手高亮,监听手柄松开钥匙,门把手高亮消失,而后通过碰撞检测,来实现触碰后的开门动画逻辑等。

using UnityEngine;using UnityEngine.Events;using Valve.VR.InteractionSystem;/// /// 物体拾取交互/// public class SteamVR_InteractGrab : MonoBehaviour{    private Throwable throwable;    private void Awake()    { throwable = GetComponent<Throwable>();    }    private void Start()    { OnGrabStart = () => Debug.Log("开始拾取:" + transform.name); OnGrabed = (hand) => { Debug.Log(hand.name + "拾取中"); }; OnGrabEnd = () => Debug.Log("结束拾取:" + transform.name);    }    ///     /// 强制放下物体    ///     public void ForceDrop() { throwable.interactable.attachedToHand.DetachObject(gameObject); }    ///     /// 委托-开始拾取    ///     public UnityAction OnGrabStart { set => throwable.onPickUp.AddListener(value); }    ///     /// 委托-拾取中    ///     public UnityAction<Hand> OnGrabed { set => throwable.onHeldUpdate.AddListener(value); }    ///     /// 委托-结束拾取    ///     public UnityAction OnGrabEnd { set => throwable.onDetachFromHand.AddListener(value); }}

Throwable组件分别对拾取、拾取中、松开物体都有事件机制,我们只需要编写脚本来监听事件即可。
本脚本为了方便测试,在Start中进行了监听,各位同学可采用继承的方式对其赋值或通过外部脚本对其赋值。
将此脚本挂载至CubeA上,运行测试
SteamVR 2.x 手柄拾取3D物体(13)

四、拓展

大家应该有注意到上面的脚本写了一个额外的方法 ForceDrop(),用来强制放下物体。
为什么要这样做呢?可以回顾一下上述的第二个案例(拾取螺丝,安装位置高亮,触碰后安装到某个位置),处理逻辑如下:
1、监听螺丝拾取,通知安装位置高亮
2、碰撞检测,螺丝与安装位置碰撞后,螺丝要处于被放下状态,并且螺丝位置要对应到指定安装位置
这样就很容易理解了,在碰撞检测后,调用ForceDrop()函数,强制放下螺丝,并且修改螺丝的Position、Rotation、Collider、RigidgeBody状态,就能完美的处理上述案例,各位同学如果感兴趣,可以自己动手试一下。

神漫画