一、几个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的设备,但这个功能只能在编辑器模式下生效。