You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity中检测Meta XR可抓取对象的抓取与释放事件?

基于Meta XR Interactions SDK实现抓取/释放状态检测与日志输出

核心思路

Meta XR Interactions SDK的官方可抓取组件(XRGrabInteractable)以及你自定义的GrabInteractible/HandGrabInteractible,都可以通过事件订阅的方式监听抓取、释放状态。以下是具体实现方案:


方案1:基于自定义组件的事件扩展(适配你的GrabInteractible.cs)

如果你的GrabInteractible是基于SDK封装的自定义组件,先在组件内暴露抓取/释放事件:

using System;
using UnityEngine;

public class GrabInteractible : MonoBehaviour
{
    // 已有抓取逻辑代码...

    // 定义抓取开始/结束的事件(供外部订阅)
    public event Action OnGrabStarted;
    public event Action OnGrabEnded;

    // 假设你已有触发抓取的方法,在逻辑执行时调用事件
    private void TriggerGrab()
    {
        // 你的抓取逻辑(比如锁定位置、关联手部)
        OnGrabStarted?.Invoke();
    }

    // 触发释放的方法
    private void TriggerRelease()
    {
        // 你的释放逻辑(比如解除锁定、恢复物理状态)
        OnGrabEnded?.Invoke();
    }
}

然后创建一个通用的反馈脚本,挂在每个立方体上:

using UnityEngine;

public class GrabFeedback : MonoBehaviour
{
    [SerializeField] private GrabInteractible targetGrabComponent;
    [SerializeField] private string objectDisplayName; // 比如"红色立方体"

    private void OnEnable()
    {
        if (targetGrabComponent != null)
        {
            targetGrabComponent.OnGrabStarted += LogGrabEvent;
            targetGrabComponent.OnGrabEnded += LogReleaseEvent;
        }
    }

    private void OnDisable()
    {
        if (targetGrabComponent != null)
        {
            targetGrabComponent.OnGrabStarted -= LogGrabEvent;
            targetGrabComponent.OnGrabEnded -= LogReleaseEvent;
        }
    }

    private void LogGrabEvent()
    {
        Debug.Log($"\"{objectDisplayName}被抓取了!\"");
    }

    private void LogReleaseEvent()
    {
        Debug.Log($"\"{objectDisplayName}被释放了!\"");
    }
}

配置步骤

  1. 给红、蓝、绿立方体分别挂上GrabFeedback脚本
  2. 在Inspector面板中,将每个立方体的GrabInteractible组件拖入targetGrabComponent字段
  3. 给objectDisplayName分别赋值为"红色立方体"、"蓝色立方体"、"绿色立方体"

方案2:直接使用官方XRGrabInteractable组件

如果你的项目直接使用SDK官方的XRGrabInteractable组件,无需自定义事件,直接订阅官方提供的选择事件(抓取属于SDK中的"选择"操作):

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class XRGrabFeedback : MonoBehaviour
{
    [SerializeField] private XRGrabInteractable xrGrabInteractable;
    [SerializeField] private string objectDisplayName;

    private void OnEnable()
    {
        if (xrGrabInteractable != null)
        {
            xrGrabInteractable.selectEntered.AddListener(OnGrabbed);
            xrGrabInteractable.selectExited.AddListener(OnReleased);
        }
    }

    private void OnDisable()
    {
        if (xrGrabInteractable != null)
        {
            xrGrabInteractable.selectEntered.RemoveListener(OnGrabbed);
            xrGrabInteractable.selectExited.RemoveListener(OnReleased);
        }
    }

    private void OnGrabbed(SelectEnterEventArgs args)
    {
        Debug.Log($"\"{objectDisplayName}被抓取了!\"");
    }

    private void OnReleased(SelectExitEventArgs args)
    {
        Debug.Log($"\"{objectDisplayName}被释放了!\"");
    }
}

关键注意事项

  • 事件订阅必须在OnDisable中取消,避免对象销毁后触发空引用异常
  • 如果你使用HandGrabInteractible,只需将上述代码中的GrabInteractible替换为HandGrabInteractible,确保该组件同样暴露了OnGrabStarted/OnGrabEnded事件

内容的提问来源于stack exchange,提问作者Yoav Linder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:52:39