一、几个Unity XR Interaction Toolkit学习地址
1.B站视频
https://www.bilibili.com/video/BV11q4y1b74z/?spm_id_from=333.999.0.0&vd_source=8125d294022d2e63a58dfd228a7fcf63
https://www.bilibili.com/video/BV13b4y177J4/?spm_id_from=333.999.0.0&vd_source=8125d294022d2e63a58dfd228a7fcf63
https://www.bilibili.com/video/BV1vm4y1d7y7/?spm_id_from=333.999.0.0&vd_source=8125d294022d2e63a58dfd228a7fcf63
2.官方文档
https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@2.2/manual/index.html
3.其它文章
http://www.devacg.com/?post=1500
二、抓取
1.改造XR Interaction Toolkit
因为XR Interaction Toolkit的功能还比较基础,在业务开发中往往不能满足需求,所以要对插件进行改造。
1)把插件包从Package移到工程
具体操作参考:https://blog.csdn.net/linjf520/article/details/125738218
2)改造物体抓取后的父节点
XR Interaction Toolkit 中提供的抓取,被抓取的物体没有父节点,但我遇到的业务需求需要把模型放到手的节点下,这时就绪要改造一下抓取脚本: XRGrabInteractable
 在抓取的方法中穿入控制器
 

3)写一个子类重载Grab()方法,来获取抓取物体的手
    public class GrabModel : XRGrabInteractable
    {
        private bool m_IsLeft;
        protected override void Grab(IXRSelectInteractor xRSelectInteractor)
        {
            base.Grab(xRSelectInteractor);
            m_IsLeft = xRSelectInteractor.transform.parent.GetComponent<HandBase>().isLeft;
        }
        protected override void Drop()
        {
            base.Drop();
            FindGrababbleInfor
        }
    }
三、获取手柄按键状态
1.Trigger 键获取
        [SerializeField] private ActionBasedController leftControl; //绑定左手控制器
        [SerializeField] private ActionBasedController rightControl;  //绑定右手控制器
            if (leftControl.activateAction.action.triggered)
            {
                Log.Info("按下左手柄上的Trigger键");
            }
            if (rightControl.activateAction.action.triggered)
            {
                Log.Info("按下右手柄上的Trigger键");
            }
2.Grab 键获取
            if (leftControl.selectAction.action.triggered)
            {
                Log.Info("按下左手柄上的Grip键");
            }
            if (rightControl.selectAction.action.triggered)
            {
                Log.Info("按下右手柄上的Grip键");
            }
3.A\B\X\Y 键监听
A\B\X\Y 键暂时没找到XR Interaction Toolkit中的获取方式,所以我这里使用了Input.InputDevices中的监听
            InputDevice rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
            if (rightHandDevice.isValid)
            {
                bool rightPrimaryButton;
                //如果一直按住,将持续返回true
                rightHandDevice.IsPressed(InputHelpers.Button.PrimaryButton, out rightPrimaryButton);
                if(rightPrimaryButton != m_RightPrimaryButton)
                {
                    m_RightPrimaryButton = rightPrimaryButton;
                    if (m_RightPrimaryButton)
                    {
                        Log.Info("按下A键");
                    }
                }
                         bool rightSecondaryButton;
                //如果一直按住,将持续返回true
                rightHandDevice.IsPressed(InputHelpers.Button.SecondaryButton, out rightSecondaryButton);
                if (rightSecondaryButton != m_RightSecondaryButton)
                {
                    m_RightSecondaryButton = rightSecondaryButton;
                    if (m_RightSecondaryButton)
                    {
                        Log.Info("按下B键");
                    }
                }
            }
            
            InputDevice leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
            if (leftHandDevice.isValid)
            {
                bool leftPrimaryButton;
                //如果一直按住,将持续返回true
                            rightHandDevice.IsPressed(InputHelpers.Button.PrimaryButton, out leftPrimaryButton);
                if (leftPrimaryButton != m_LeftPrimaryButton)
                {
                    m_LeftPrimaryButton = leftPrimaryButton;
                    if (m_LeftPrimaryButton)
                    {
                        Log.Info("按下X键");
                    }
                }
                
                bool leftSecondaryButton;
                //如果一直按住,将持续返回true
                rightHandDevice.IsPressed(InputHelpers.Button.SecondaryButton, out leftSecondaryButton);
                if (leftSecondaryButton != m_LeftSecondaryButton)
                {
                    m_LeftSecondaryButton = leftSecondaryButton;
                    if (m_LeftSecondaryButton)
                    {
                        Log.Info("按下Y键");
                    }
                }
            }
四、其它问题
1.UnityXR 无法调起HTC Vive头盔。
发现是因为使用HTC Cosmos 安装了VIVEConsole 导致UnityXR无法调起Vive头盔。解决方案:就是把VIVEConsole卸载。
2.使用HTC Vive头盔手柄经常失灵。
UnityXR中会调起头盔的佩戴识别,当没有戴上时手柄就会进入休眠状态。解决方案:把识别佩戴的摄像头贴起来。(理论上应该可以设置识别的开关, 但没有找到)
3.HTC Cosmos 的 A/B/X/Y 键无法响应。
把OpenXR中的Interaction Profile设置换成Oculus(之前选的是HTC Vive)
 
4.UnityXR调起SteamVR
在PlayModeOpenXRRuntime的选项中可以选择SteamVR,即可调起SteamVR,从而调起支持SteamVR的设备,但这个功能只能在编辑器模式下生效。
 



















