MRTK2转MRTK3:监听ObjectManipulator抓取事件及区分交互类型
解决MRTK3中通过脚本监听ObjectManipulator抓取事件的问题
一、直接监听ObjectManipulator内置事件
ObjectManipulator组件本身就暴露了抓取相关的原生事件,无需额外添加Receiver,直接通过代码绑定即可:
// 获取或添加ObjectManipulator组件 ObjectManipulator manipulator = GetComponent<ObjectManipulator>() ?? gameObject.AddComponent<ObjectManipulator>(); // 绑定抓取开始与结束事件 manipulator.OnManipulationStarted.AddListener(OnGrabStarted); manipulator.OnManipulationEnded.AddListener(OnGrabEnded); // 抓取开始回调 private void OnGrabStarted(ManipulationEventData eventData) { // 此处编写抓取触发后的逻辑,比如修改物体状态、播放反馈音效等 } // 抓取结束回调 private void OnGrabEnded(ManipulationEventData eventData) { // 此处编写抓取释放后的逻辑 }
二、区分抓取、戳、凝视等不同交互类型
如果需要精准区分不同交互行为,可通过MRTKBaseInteractable的事件,结合交互器接口判断类型(ObjectManipulator已内置该组件,无需额外添加):
MRTKBaseInteractable interactable = GetComponent<MRTKBaseInteractable>(); // 绑定交互进入与退出事件 interactable.SelectEntered.AddListener(OnSelectEntered); interactable.SelectExited.AddListener(OnSelectExited); private void OnSelectEntered(SelectEnterEventArgs args) { // 判断交互器类型,区分不同操作 if (args.interactorObject is IMRTKGrabInteractor) { // 抓取交互触发 OnGrab(); } else if (args.interactorObject is IMRTKPokeInteractor) { // 戳交互触发 OnPoke(); } else if (args.interactorObject is XRRayInteractor) { // 射线/凝视交互触发 OnGazeSelect(); } } private void OnSelectExited(SelectExitEventArgs args) { // 同理判断交互结束类型 if (args.interactorObject is IMRTKGrabInteractor) { OnGrabRelease(); } } // 自定义交互逻辑方法 private void OnGrab() { /* 抓取开始逻辑 */ } private void OnGrabRelease() { /* 抓取结束逻辑 */ } private void OnPoke() { /* 戳交互逻辑 */ } private void OnGazeSelect() { /* 凝视选择逻辑 */ }
三、关键注意事项
- ObjectManipulator内部已集成
MRTKBaseInteractable,手动重复添加会被Unity忽略,无需额外挂载。 IMRTKGrabInteractor、IMRTKPokeInteractor是MRTK3标记交互类型的核心接口,通过类型判断可精准区分不同手部/射线操作。- 若仅需监听抓取的开始与结束,直接使用ObjectManipulator的
OnManipulationStarted和OnManipulationEnded是最简洁的方案,这两个事件专门针对抓取移动场景设计。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

