前言
前面我们介绍了如何抓取物体,今天我们来说一下如何和3D的物体进行交互,得到接触的事件回调。
交互的两种方式:
1.直接抓取或者射线抓取物体,得到接触回调
2.射线或者手部触摸物体后,得到接触回调
准备工作
有了前两篇的配置介绍,我们就不在详细说明这些了,大家自行复习
Unity之OpenXR+XR Interaction Toolkit接入Pico VR一体机
Unity之OpenXR+XR Interaction Toolkit接入HTC Vive
我们新建一个3D(URP)工程
然后通过PackageManager安装XR Interaction ToolKit插件。
配置好XR Interaction Toolkit的Preset
新建一个3D场景
放置几个简单的3D几何体到场景中
准备工作完毕
添加XR Origin
我们在Hierarchy试图窗口,点击鼠标右键创建一个XR->XR Origin(VR)对象
默认XR Origin上面的LeftHandController和RightHandController是添加的RayInteractor射线交互器。RayInteractor包含了射线点击和抓取功能,如果要使用手部直接抓取功能,我们可以把HandControll的RayInteractor替换成DirectInteractor。我们这里就以RayInteractor为示例,介绍一下如何实现射线和物体交互
注意检查下XR Controller(Action-based)组件是否设置完毕。
设置3D物体
如果希望手柄发射的射线可以和3D物体进行交互,那么除了给手柄添加RayInteractor之外,3D物体上面还必须添加交互组件。XRInteraction Toolkit给我们提供了几个组件
XR Grab Interacable,用于物体可以被抓取
XR Simple Interacable,用于物体可以被射线和手柄检测到。
我们在创建个几何体中选择一个,添加上面两个组件中的一个即可。如果你想让物体再被射线点击的同时被抓起来,那么就添加Grab Interaction。但是我想演示的是,我们射线碰到物体后,得到回调即可,无需被抓起来。
好了,我们给圆柱体添加XR Simple Interacable组件,如下图所示:
属性介绍:
Interaction Layer Mask :用于设置当前物体的Layer,可以通过手柄交互的层遮罩来控制那些物体可以交互,那些物体不交互。
Colliders:设置当前可交互物体的碰撞,注意必须是碰撞,触发器无效。可以不设置,运行时组件会自动获取游戏对象的所有碰撞组件(包括子节点的碰撞),如果手动设置了一个,那么运行时组件就不会再自动获取其他碰撞组件了。
Distance Calculation Mode:
Custom Reticle:
Select Mode:选中模式,是单击选中 还是 双击选中
Interactable Filters:交互过滤器
Interactable Events:交互事件,控制交互的回调事件,也可以代码绑定。
交互事件回调
好了,XR Origin + Hand Controller 和 XR Simgle Interactable都设置好了,可以开始测试交互了。
我们写一个MonoBehaviour脚本,添加到HandController手柄上,用于接受射线和物体交互的事件。
脚本代码如下:
namespace GT.Hotfix
{
public class VRHandItem : HandItem
{
//射线交互组件
private XRRayInteractor m_XrRayInteractor;
protected override void Start()
{
m_XrRayInteractor = GetComponentInChildren<XRRayInteractor>();
//代码绑定选中进入事件
m_XrRayInteractor.selectEntered.AddListener(OnRaySelectEntered);
//代码绑定选中离开事件
m_XrRayInteractor.selectExited.AddListener(OnRaySelectExited);
}
//选中进入回调
void OnRaySelectEntered(SelectEnterEventArgs args)
{
var attach = args.interactableObject.GetAttachTransform(args.interactorObject);
Debug.Log("Ray触摸进入:" + attach.name);
}
//选中离开回调
private void OnRaySelectExited(SelectExitEventArgs args)
{
var attach = args.interactableObject.GetAttachTransform(args.interactorObject);
Debug.Log("Ray触摸结束:" + attach.name);
}
}
}
我们把脚本添加到左右手任意一个HandController上面,然后运行游戏。
我们手柄射线选中物体后,点击G按键,触发Select事件,得到事件回调,日志打印如下: