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

如何禁用XRRayInteractor中抓取对象随玩家摇杆移动的联动?

解决方案(适配Unity 2021.3.1f + XR Interaction Toolkit 2.2.0)

首先明确:没有直接勾选就能实现的默认设置,但可以通过简单代码结合XR内置组件快速实现需求。

实现步骤

  1. 给挂载了XRGrabInteractable的目标对象新增一个C#脚本,比如命名为FreezeGrabbedObjectOnMove.cs
  2. 脚本逻辑核心:
    • 监听负责玩家移动的控制器摇杆输入
    • 检测到摇杆移动时,让抓取对象脱离控制器父级,保持当前世界位置与旋转
    • 摇杆输入停止后,重新将对象附着回控制器的抓取点位

代码示例:

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

public class FreezeGrabbedObjectOnMove : MonoBehaviour
{
    [SerializeField] private XRController movementController; // 绑定负责移动的控制器(左/右)
    [SerializeField] private XRGrabInteractable grabInteractable;
    private Transform originalAttachTransform;
    private Vector3 originalLocalPos;
    private Quaternion originalLocalRot;
    private bool isMoving;

    void Update()
    {
        // 检测摇杆输入(轴向量超过阈值判定为移动)
        if (movementController.inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 axis))
        {
            isMoving = axis.magnitude > 0.1f;
        }

        if (grabInteractable.isSelected)
        {
            if (isMoving)
            {
                // 移动时脱离控制器,固定世界位置
                if (transform.parent == grabInteractable.attachTransform)
                {
                    originalAttachTransform = grabInteractable.attachTransform;
                    originalLocalPos = transform.localPosition;
                    originalLocalRot = transform.localRotation;
                    transform.SetParent(null);
                }
            }
            else
            {
                // 停止移动后重新附着回控制器
                if (transform.parent == null && originalAttachTransform != null)
                {
                    transform.SetParent(originalAttachTransform);
                    transform.localPosition = originalLocalPos;
                    transform.localRotation = originalLocalRot;
                }
            }
        }
        else
        {
            // 未抓取时重置状态
            originalAttachTransform = null;
            isMoving = false;
        }
    }
}
  1. 脚本配置:
    • 在Inspector面板中,将movementController绑定到你设置的负责玩家移动的控制器(比如左控制器)
    • grabInteractable会自动获取当前对象上的组件,也可手动指定

额外优化(可选)

如果想避免位置跳变,可在重新附着时使用插值平滑过渡:

// 替换停止移动后的附着代码段
if (transform.parent == null && originalAttachTransform != null)
{
    transform.SetParent(originalAttachTransform);
    transform.localPosition = Vector3.Lerp(transform.localPosition, originalLocalPos, Time.deltaTime * 10f);
    transform.localRotation = Quaternion.Lerp(transform.localRotation, originalLocalRot, Time.deltaTime * 10f);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:15:35