PICO使用MRTK3手势交互

发布时间 2023-11-03 17:36:33作者: 陌洛

1、下载MRTK示例项目

https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity

下载完成后切入mrtk3分支

2、使用Unity打开示例工程MRTKDevTemplate(MixedRealityToolkit-Unity\UnityProjects\MRTKDevTemplate),Unity版本要求再2021.3长期支持板及以上

3、导入UnityIntegrationSDK,Pico官网下载2.3.0

4、打开ProjectSetting,XR-Plug设置如下

 5、安卓设置OtherSetting设置如下

6、下载开源项目PicoMRTK3,复制PicoMRTK3Support文件夹到自己的工程目录下(PicoMRTK3-main\PicoMRTK3\Assets\Scripts\PicoMRTK3Support)

https://github.com/Phantomxm2021/PicoMRTK3

7、配置脚本编译Other Settings Script Compilation里进行设置,添加PICO_INSTALL和MRTK3_INSTALL,添加完后点击Apply

 8、MRTK3配置如下,选项打开没有默认文件就新建一个对应的asset文件,属性值保持默认即可

 配置项目选择HandInteractionExamples场景,保险起见可以复制出来一个场景配置:

9、在MRTK XR Rig物体上添加PXR_Manager组件,并勾选Hand Tracking

10、选中Main Camera关闭CameraSettingsManager脚本组件,不然不能开启Pico透视

11、选中MRTK RightHand Controller打开ArticulatedHandController脚本替换UpdateInput方法:

        protected override void UpdateInput(XRControllerState controllerState)
        {
            base.UpdateInput(controllerState);

            using (UpdateTrackingInputPerfMarker.Auto())
            {
                if (controllerState == null)
                    return;

                // Cast to expose hand state.
                ArticulatedHandControllerState handControllerState = controllerState as ArticulatedHandControllerState;

                // If we still don't have an aggregator, then don't update selects.
                if (XRSubsystemHelpers.HandsAggregator == null) { return; }

                bool gotPinchData = XRSubsystemHelpers.HandsAggregator.TryGetPinchProgress(
                handNode,
                out bool isPinchReady,
                out bool isPinching,
                out float pinchAmount
            );

                // If we got pinch data, write it into our select interaction state.
                if (gotPinchData)
                {
                    // Workaround for missing select actions on devices without interaction profiles
                    // for hands, such as Varjo and Quest. Should be removed once we have universal
                    // hand interaction profile(s) across vendors.

                    // Debounce the polyfill pinch action value.
                    bool isPinched = pinchAmount >= (pinchedLastFrame ? 0.9f : 1.0f);
#if !PICO_INSTALL
    // Inject our own polyfilled state into the Select state if no other control is bound.
    if (!selectAction.action.HasAnyControls())
{
    controllerState.selectInteractionState.active = isPinched;
    controllerState.selectInteractionState.activatedThisFrame = isPinched && !pinchedLastFrame;
    controllerState.selectInteractionState.deactivatedThisFrame = !isPinched && pinchedLastFrame;
}
 
    if (!selectActionValue.action.HasAnyControls())
{
    controllerState.selectInteractionState.value = pinchAmount;
}
 
    // Also make sure we update the UI press state.
    if (!uiPressAction.action.HasAnyControls())
{
    controllerState.uiPressInteractionState.active = isPinched;
    controllerState.uiPressInteractionState.activatedThisFrame = isPinched && !pinchedLastFrame;
    controllerState.uiPressInteractionState.deactivatedThisFrame = !isPinched && pinchedLastFrame;
}
 
    if (!uiPressActionValue.action.HasAnyControls())
{
    controllerState.uiPressInteractionState.value = pinchAmount;
}
 
    pinchedLastFrame = isPinched;
#else
                    // Debounced.

                    controllerState.selectInteractionState.active = isPinched;
                    controllerState.selectInteractionState.activatedThisFrame = isPinched && !pinchedLastFrame;
                    controllerState.selectInteractionState.deactivatedThisFrame = !isPinched && pinchedLastFrame;
                    controllerState.selectInteractionState.value = pinchAmount;


                    controllerState.uiPressInteractionState.active = isPinched;
                    controllerState.uiPressInteractionState.activatedThisFrame = isPinched && !pinchedLastFrame;
                    controllerState.uiPressInteractionState.deactivatedThisFrame = !isPinched && pinchedLastFrame;
                    controllerState.uiPressInteractionState.value = pinchAmount;

                    pinchedLastFrame = isPinched;
#endif
                }

                handControllerState.PinchSelectReady = isPinchReady;
            }
        }

12、配置手部模型,选中MRTK RightHand Controller(左右手都要设置)配置如下,HandRight预制体在Packages→ PICO Integration→Assets→Resources→Prefabs下

 

至此配置完成,打包apk即可调试