XR Interaction Toolkit Manual
XR Interaction Toolkit Examples
Unity - Manual: XR Input
Unity - Packages: Input System
扩展现实(Extended Reality,简称XR),是AR(增强现实)、VR(虚拟现实)、MR(混合现实)等多种技术的统称。
一个高级的,基于组件的交互系统,用于创建VR和AR体验。它提供了一个框架,以及一个将这两种类型的组件连接在一起的交互管理器。它还包含了您可以用于运动和绘图视觉效果的组件。
Tracking Origin Mode
○ Not Specified:使用输入设备的默认跟踪原点模式。
○ Device: 输入设备将相对于第一个已知位置进行跟踪。
○ Floor:输入设备将相对于地板上的位置进行跟踪。
需要在希望被抓取的对象上挂 XRGrabInteractable 脚本。找到 XR Origin/Camera Offset/LeftHand Controller 对象上的 XRRayInteractor 脚本上的 Force Grab 属性,当此属性为true时,对象将被瞬移到手上。当此属性为false时,对象将被固定在手柄射线的端点上。
XRRayInteractor 脚本上找到 Interactor Events 属性,展开后可以设置相互作用事件回调。手柄进入事件(Hover Entered)、手柄离开事件(Hover Exited)、抓取事件(Select Entered)、释放事件(Select Exited)。
XRRayInteractor 脚本上找到 Haptic Events 属性,展开后可以为一些事件设置振动参数。
手柄交互由 XR Origin/Camera Offset/LeftHand Controller 上挂的 ActionBasedController 组件控制。ActionBasedController 负责将从XR输入子系统(XR input subsystem)中获取到的特征值转成XR交互状态(XR interaction state),例如 “选中”,以及控制设备(如,手柄)与控制模型之间的姿态同步。
ActionBasedController rightHandController;
//只会在按下那一刻返回true
if (rightHandController.activateAction.action.triggered)
{
Debug.Log("按下手柄上的Trigger键");
}
ActionBasedController rightHandController;
InputActionPhase phase = rightHandController.activateAction.action.phase;
switch(phase)
{
case InputActionPhase.Disabled:
material.SetColor("_Color", Color.red);
break;
case InputActionPhase.Waiting://Trigger键未按下
material.SetColor("_Color", Color.yellow);
break;
case InputActionPhase.Started:
material.SetColor("_Color", Color.green);
break;
case InputActionPhase.Performed://Trigger键按下
material.SetColor("_Color", Color.blue);
break;
case InputActionPhase.Canceled:
material.SetColor("_Color", Color.white);
break;
}
当 Trigger 键处于 InputActionPhase.Performed 阶段时 IsPressed() 方法返回 true
bool isTriggerPressed = rightHandController.activateAction.action.IsPressed();
WasPressedThisFrame()
在触发按下动作帧中返回true
WasPerformedThisFrame()
在保持按下状态帧中返回true
WasReleasedThisFrame()
在触发释放动作帧中返回true
IsPressed()
只要超过按钮按下阈值就返回true
ActionBasedController rightHandController;
//只会在按下那一刻返回true
if (rightHandController.selectAction.action.triggered)
{
Debug.Log("按下手柄上的Grip键");
}
//如果Grip处于按下状态,会一直返回true
if (rightHandController.selectAction.action.IsPressed())
{
Debug.Log("按住手柄上的Grip键");
}
用 triggered 属性判断按下动作,用 IsPressed() 判断是否持续按住不放。
activateAction.action.IsPressed() 与 activateActionValue.action.IsPressed() 没有区别。
namespace UnityEngine.XR.Interaction.Toolkit
{
public static class InputHelpers
{
public enum Button
{
None = 0,
MenuButton = 1,//菜单键
Trigger = 2,//扳机键
Grip = 3,//抓取键
TriggerButton = 4,//扳机键
TriggerPressed = 4,//扳机键
GripButton = 5,//抓取键
GripPressed = 5,//抓取键
PrimaryButton = 6,//右手A键按下 或 左手X键按下
PrimaryTouch = 7,//右手A键触摸 或 左手X键触摸
SecondaryButton = 8,//右手B键按下 或 左手Y键按下
SecondaryTouch = 9,//右手B键触摸 或 左手Y键触摸
Primary2DAxisTouch = 10,//右手摇杆触摸
Primary2DAxisClick = 11,//右手摇杆Click
Secondary2DAxisTouch = 12,//左手摇杆触摸
Secondary2DAxisClick = 13,//左手摇杆Click
PrimaryAxis2DUp = 14,//右手摇杆向上
PrimaryAxis2DDown = 15,//右手摇杆向下
PrimaryAxis2DLeft = 16,//右手摇杆向左
PrimaryAxis2DRight = 17,//右手摇杆向右
SecondaryAxis2DUp = 18,//左手摇杆向上
SecondaryAxis2DDown = 19,//左手摇杆向下
SecondaryAxis2DLeft = 20,//左手摇杆向左
SecondaryAxis2DRight = 21//左手摇杆向右
}
}
}
1. 存在两个InputDevice类,分别是 UnityEngine.XR.InputDevice 和 UnityEngine.InputSystem.InputDevice; 建议定义两个别名:
using XRInputDevice = UnityEngine.XR.InputDevice;
using ISInputDevice = UnityEngine.InputSystem.InputDevice;
//检测右边手柄扳机键是否按下
XRInputDevice rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
if (rightHandDevice.isValid)
{
bool isRightTriggerDown;
//如果一直按住,将持续返回true
rightHandDevice.TryGetFeatureValue(PXR_Usages.triggerTouch, out isRightTriggerDown);
}
UnityEngine.XR.Interaction.Toolkit.InputHelpers 类为 UnityEngine.XR.InputDevice 提供了扩展方法:
public static bool IsPressed(this InputDevice device, Button button, out bool isPressed, float pressThreshold = -1);
//检测右边手柄扳机键是否按下
XRInputDevice rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
if (rightHandDevice.isValid)
{
bool isPressed;
//如果一直按住,将持续返回true
//经测试:Button.Trigger、Button.TriggerButton、Button.TriggerPressed 3种效果等同
rightHandDevice.IsPressed(InputHelpers.Button.TriggerPressed, out isPressed);
}
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class Test : MonoBehaviour
{
public ActionBasedController rightHandController;
public XRSimpleInteractable interactable;
private void Update()
{
//判断手柄射线是否指向模型
if (interactable.isHovered)
{
//判断是否按下Trigger键
//只会在按下那一刻返回true
if (rightHandController.activateAction.action.triggered)
{
Debug.Log("按下手柄上的Trigger键");
}
}
}
}
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using UnityEngine.XR.Interaction.Toolkit;
/// <summary>
/// 挂在模型上,用来监听手柄板机键(Trigger)是否按下
/// </summary>
[RequireComponent(typeof(XRSimpleInteractable))]
public class XRTriggeredEvent : MonoBehaviour
{
public ActionBasedController leftHandController;
public ActionBasedController rightHandController;
public XRSimpleInteractable interactable;
[Serializable]
public class OnTriggeredEvent : UnityEvent { }
[FormerlySerializedAs("triggered")]
[SerializeField]
private OnTriggeredEvent m_OnTriggered = new OnTriggeredEvent();
private void Update()
{
if (interactable.isHovered)
{
bool leftTriggered = false;
bool rightTriggered = false;
if (leftHandController != null)
{
leftTriggered = leftHandController.activateAction.action.triggered;
}
if (rightHandController != null)
{
rightTriggered = rightHandController.activateAction.action.triggered;
}
if (leftTriggered || rightTriggered)
{
//在模型上按下Trigger键(左手或右手)
m_OnTriggered?.Invoke();
}
}
}
}
//获取右手摇杆值
XRInputDevice rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
if (rightHandDevice.isValid)
{
//取值范围 [-1,1]
//摇杆推到最上面时返回1,推到最下面时返回-1
float singleValue;
rightHandDevice.TryReadSingleValue(InputHelpers.Button.PrimaryAxis2DUp, out singleValue);
}
建议使用ActionBasedController代替XRController。与ActionBasedController相比,此行为不需要那么多的初始设置,但是输入处理的可定制性较低,并且XRDeviceSimulator不能用于驱动此行为。
设置要使用的输入处理系统
[Edit]->Project Settings->Player->Active Input Handling
XR UI Input Module 是与 Event System 关联所必须的组件。 XR UI Input Module 与 XR Ray Interactor(XR射线交互器)协同工作,以确保正确处理与UI的XRI交互。 它还处理来自其他非XR源(如游戏板或鼠标)的输入(如果配置为这样做)。
Enable Builtin Actions As Fallback
如果勾选,这将允许默认的鼠标、游戏板或操纵杆操作在当前输入系统设备配置的情况下驱动UI。