Hololens 导航使用点击并按住手势错误?

Hololens Navigation using tap and hold gesture bug?

使用来自 HoloToolkit 资产和实现代码的 InputManager 预制件,用户可以点击并按住给定的对象,然后向左或向右移动他们的手(沿着 x 平面)来旋转对象Y 轴或上下(沿 y 平面)旋转对象在 X 轴上。

但是似乎有一个错误。如果用户注视离开对象,旋转会立即停止,直到用户注视 returns 到对象。这是预期的功能吗?如果是这样,如何通过导航手势保留正在更改的当前对象并允许它继续被操纵直到用户手离开 FOV 或用户释放点按手势?

目标是利用点击并按住手势,但不要求用户在整个旋转过程中将目光锁定在对象上。这对于小的或形状笨拙的物体来说是相当困难的。

实现代码:

[Tooltip("Controls speed of rotation.")]
public float RotationSensitivity = 2.0f;

private float rotationFactorX, rotationFactorY;

public void OnNavigationStarted(NavigationEventData eventData)
{
    Debug.Log("Navigation started");
}
public void OnNavigationUpdated(NavigationEventData eventData)
{
    rotationFactorX = eventData.CumulativeDelta.x * RotationSensitivity;

    rotationFactorY = eventData.CumulativeDelta.y * RotationSensitivity;

    //control structure to prevent dual axis movement
    if (System.Math.Abs(eventData.CumulativeDelta.x) > System.Math.Abs(eventData.CumulativeDelta.y))
    {
        //rotate focusedObject along Y-axis
        transform.Rotate(new Vector3(0, -1 * rotationFactorX, 0));
    }
    else
    {
        //rotate focusedObject along X-axis
        transform.Rotate(new Vector3(-1 * rotationFactorY, 0, 0));
    }
}
public void OnNavigationCompleted(NavigationEventData eventData)
{
    Debug.Log("Navigation completed");
}
public void OnNavigationCanceled(NavigationEventData eventData)
{
    Debug.Log("Navigation canceled");
}

您需要调用这些方法:

    NavigationRecognizer = new GestureRecognizer();
    NavigationRecognizer.SetRecognizableGestures(GestureSettings.Tap);
    NavigationRecognizer.TappedEvent += NavigationRecognizer_TappedEvent;
    ResetGestureRecognizers();

这是针对点击事件,但执行其他操作很简单,只需为它们添加事件回调并在 SetRecognizableGestures() 调用上使用 | OR 选择器即可。例如

    NavigationRecognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.NavigationX);

Draco18 的答案更安全,但这个解决方案同样有效,因为 InputManager 预制件为我们实现了一个堆栈。

导航开始时,清空堆栈并将 'Navigated' 中的对象压入堆栈,

InputManager.Instance.ClearModalInputStack(); InputManager.Instance.PushModalInputHandler(gameObject);

导航完成或取消时,将其弹出堆栈。 InputManager.Instance.PopModalInputHandler();

将此添加到您自己的实施脚本中,无需调整 InputManager 上任何预先存在的脚本。