UnityXR SDK 的输入子系统

XR SDK 输入子系统

XR SDK 输入子系统是 unityXR sdk 中 用于获取按钮、摇杆和设备跟踪信息的接口。是用户控制数据输入到 Unity 引擎的各种输入端点中的核心子系统。Unity 会将输入信息报告给 InputDevicesInputSystem

XR 输入信息的同步分为以下步骤

1.报告设备连接和断开

2.填写链接设备的定义信息

3.更新设备的状态

4.响应相关事件和查询

5.向Inputsystem注册设备布局

报告设备链接和断开

IUnityXRInputInterface 中的两个 API 可处理设备连接和断开连接:

IUnityXRInputInterface.InputSubsystem_DeviceConnected

这会报告一个新设备。提供程序提供的 UnityXRInternalInputDeviceId 可以是任何值,只要它表示内部唯一的设备并且没有两个设备与来自相同提供程序的相同 Id 连接。设备只能在输入提供程序生命周期的开始与停止事件之间连接。在调用 IUnityXRInputProvider.Start 时任何已连接的设备在该回调期间应进行报告。

一旦设备报告为已连接,Unity 便会在下一个输入更新循环中使用提供的 UnityXRInternalInputDeviceId 调用 IUnityXRInputProvider.FillDeviceDefinition,以便获取有关该设备的特定信息。

IUnityXRInputInterface.InputSubsystem_DeviceDisconnected

这会报告输入设备不再可用。仅在已将输入设备报告为已连接后,才能将它报告为已断开连接。收到 IUnityXRInputProvider.Stop 时,必须将当前连接的所有输入设备都报告为断开连接。

设备的定义

设备定义描述设备可以向 Unity 报告的功能。功能包括设备标识信息,例如设备名称、角色、制造商和序列号。设备定义还包含所有可用输入功能的索引列表。

这些设备的信息是通过UnityAPI自定义完成的

IUnityXRInputInterface.DeviceDefinition_SetName

这使提供程序可以设置设备名称。名称必须清晰、简洁,并且可被大众市场消费者所识别。这不应包括制造商的名称。此名称可通过 UnityEngine.XR.InputDevice.name 供开发者使用,在输入系统中用作 InputDevice.product。请勿将此留空。

IUnityXRInputInterface.DeviceDefinition_SetCharacteristics

这使提供程序可以指定连接的设备类型。UnityXRInputDeviceCharacteristics 是一系列有助于定义设备功能的标志。这些可更改 InputDevice 的输入系统用途。

IUnityXRInputInterface.DeviceDefinition_SetManufacturer

这使提供程序可以设置设备的制造商。制造商必须清晰、简洁,并且可被大众市场消费者所识别。此字符串可通过 UnityEngine.XR.InputDevice.manufacturer 供开发者使用,在输入系统中用作 InputDevice.manufacturer。请勿将此留空。

IUnityXRInputInterface.DeviceDefinition_SetSerialNumber

这使提供程序可以设置设备的序列号。此字符串可通过 UnityEngine.XR.InputDevice.serialNumber 供开发者使用,在输入系统中用作 InputDevice.serialNumber。这必须是此特定设备的唯一标识符,否则您应该将它留空。

在Native层中设置了相关设备的定义后,在Unity引擎中即可通过InputDevice.description 接口获取设备的相关信息。同时在注册Inputsystem布局时也需要对应到Nacive层接口设置的设备定义

添加设备功能

通过Native层以下API将输入功能添加到设备定义中

IUnityXRInputInterface.DeviceDefinition_AddFeatureWithUsage 添加一个设备输入功能,其中input feature参数的名称需要与Inputsystem布局中得到名称或别名对应,否则设备的Inputsystem布局无法生效

设备状态更新

Unity 会通过 IUnityXRInputProvider.UpdateDeviceState 在每一帧请求设备状态两次

  • kUnityXRInputUpdateTypeDynamic 是在 Unity 遍历 MonoBehaviour.Update 调用和协程继续之前的更新。这些应表示设备当前所在的位置。
  • kUnityXRInputUpdateTypeBeforeRender 就在 Unity 准备好渲染到头盔之前,以及就在调用 Application.OnBeforeRender 之前进行调用。这些调用应使用正向预测的跟踪位置,并表示您希望在显示场景时渲染场景的位置。

同时在设备状态更新中需要分别对设备的旋转位移,按键,摇杆等设备信息进行同步更新。

响应相关事件和查询

设备信息

这些包含通用化设备信息,而不是用户启动的控件。它们是用户无法直接控制的设备功能。

kUnityXRInputFeatureUsageBatteryLevel 是表示设备当前电池电量的 1D 轴功能,其中 0 表示没有电池电量,1 表示充满电。它必须始终在 [0–1] 范围内。

kUnityXRInputFeatureUsageUserPresence 是布尔值,在用户当前佩戴头盔时返回 true。

2D 轴

这些是二维模拟浮点值,例如触控板和游戏杆。这些控件通常使用拇指进行移动。它们提供 X 和 Y,应始终在 ([–1,1],[–1,1]) 范围内。

kUnityXRInputFeatureUsagePrimary2DAxis 是表示触控板或游戏杆的 2D 轴功能。0,0 是空闲位置,Y 正值表示远离控制器用户。

kUnityXRInputFeatureUsageSecondary2DAxis 是表示第二个游戏杆或触控板的 2D 轴(与 kUnityXRInputFeatureUsagePrimary2DAxis 一起使用)。0,0 是空闲位置,Y 正值表示远离控制器用户。

1D 轴

这些全部是一维模拟浮点值。此处标识了可以“半按”的按钮、触发器和其他控件。

kUnityXRInputFeatureUsageTrigger 是映射到索引启动的触发器的 1D 轴。这必须始终在 [0,1] 范围内,其中 0 是打开,1 是完全挤压。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageTriggerButton

kUnityXRInputFeatureUsageGrip 是映射到用手挤压激活握把的 1D 轴。这必须始终在 [0,1] 范围内,其中 0 是打开,1 是完全挤压。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageGripButton

二进制

这些是一维数字值。它们可以启动或不启动,但没有进一步的粒度。

kUnityXRInputFeatureUsagePrimaryButton 是表示控制器上主按钮的二进制功能。这通常用作菜单中的接受或高级按钮。如果启动了此功能,则 kUnityXRInputFeatureUsagePrimaryTouch 也必须启动(如果存在)。

kUnityXRInputFeatureUsagePrimaryTouch 是表示控制器上主按钮的触摸状态的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsagePrimaryButton

kUnityXRInputFeatureUsageSecondaryButton 是表示控制器上辅助按钮的二进制功能。这通常用作后退或备选按钮。如果启动了此功能,则 kUnityXRInputFeatureUsageSecondaryTouch 也必须启动(如果存在)。

kUnityXRInputFeatureUsageSecondaryTouch 是表示控制器上辅助按钮的触摸状态的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageSecondaryButton

kUnityXRInputFeatureUsageGripButton 是表示是否触发手动挤压的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageGrip

kUnityXRInputFeatureUsageTriggerButton 是表示是否触发手动挤压的布尔值功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageTrigger

kUnityXRInputFeatureUsageMenuButton 是表示非游戏暂停或菜单按钮的二进制功能。这对于用户而言通常不容易实现。

kUnityXRInputFeatureUsagePrimary2DAxisClick 是表示按下或单击 kUnityXRInputFeatureUsagePrimary2DAxis 2D 轴的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsagePrimary2DAxis。如果启动了此功能,则 kUnityXRInputFeatureUsagePrimary2DAxisTouch 也必须启动(如果存在)。

kUnityXRInputFeatureUsagePrimary2DAxisTouch 是表示轻触 kUnityXRInputFeatureUsagePrimary2DAxis 2D 轴的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsagePrimary2DAxis

kUnityXRInputFeatureUsageSecondary2DAxisClick 是表示按下或单击 kUnityXRInputFeatureUsageSecondary2DAxis 2D 轴的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageSecondary2DAxis。如果启动了此功能,则 kUnityXRInputFeatureUsageSecondary2DAxisTouch 也必须启动(如果存在)。

kUnityXRInputFeatureUsageSecondary2DAxisTouch 是表示轻触 kUnityXRInputFeatureUsageSecondary2DAxis 2D 轴的二进制功能。如果实现了此功能,则设备还必须实现 kUnityXRInputFeatureUsageSecondary2DAxis

Inputsystem注册设备布局

输入子系统如果需要支持Inputsystem系统,需要在设备定义时与创建的自定义InputLayout映射。

如在设备添加输入功能时,inputfeature参数需要与inputsystem布局中的元素相同才会映射,

unityInputInterface.DeviceDefinition_AddFeatureWithUsage(definition, "PrimaryButton", kUnityXRInputFeatureTypeBinary,kUnityXRInputFeatureUsagePrimaryButton);
//添加手柄控制器上主按钮,第二个参数需要与下段布局代码中的字段或别名一致,InputSystem才会生效。
unityInputInterface.DeviceDefinition_AddFeatureWithUsage(definition, "thumbstick", kUnityXRInputFeatureTypeAxis2D,kUnityXRInputFeatureUsagePrimary2DAxis);
//添加手柄控制器上的摇杆按钮。
[Preserve]
[InputControlLayout(displayName = "Example VR Controller")]
public class ExampleVRController : XRController
{
    [Preserve]
    [InputControl(aliases = new[] { "PrimaryButton" })]
    public ButtonControl exampleButton { get; private set; }
    [Preserve]
    [InputControl]
    public Vector3Control examplePosition { get; private set; }
    [Preserve]
    [InputControl]
    public QuaternionControl exampleRotation { get; private set; }
    [Preserve]
    [InputControl(aliases = new[] { "Primary2DAxis", "Joystick" })]
    public Vector2Control thumbstick { get; private set; }
    protected override void FinishSetup()
    {
        base.FinishSetup();
        exampleButton = GetChildControl<ButtonControl>("exampleButton");
        examplePosition = GetChildControl<Vector3Control>("examplePosition");
        exampleRotation = GetChildControl<QuaternionControl>("exampleRotation");
        thumbstick = GetChildControl<Vector2Control>("thumbstick");
    }
}
注册布局

最后注册布局,在XRSDK加载输入子系统时,向InputSystem注册设备布局

需要与设备定义时的信息匹配,可以匹配设备的产品名或生产商

    static class InputLayoutLoader
    {
        static InputLayoutLoader()
        {
            RegisterInputLayouts();
        }

        public static void RegisterInputLayouts()
        {
            InputSystem.RegisterLayout<ExampleVRController>(
               matches: new InputDeviceMatcher()
                   .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
                   .WithProduct("controller").WithManufacturer("xxx"));//将产品名为contoller,厂商为xxx的设备与ExampleVRController布局绑定,支持正则表达式匹配
        }
    }

XR Rig区别

在Unity创建XR Rig时有两种类型分别是

XR Rig(Device-base)

XR Rig(Action-base)

XR Rig

Device-base

创建 XR Rig(Device-base) 时,XR Rig 使用的设备输入接口为InputDevice.

通过GetDeviceAtXRNode 可以获取特定XRNode端点的输入设备。

InputDevice.TryGetFeatureValue() 获取设备可用的所有输入功能用法的列表。例如,“Trigger”或“Device Position”。

 InputDevice contrllerL = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);//获取左手柄
 bool buttonResult =false;
 contrllerL.TryGetFeatureValue(CommonUsages.triggerButton, out buttonResult); //获取左手柄中扳机键是否被按下
Action-base

创建XR Rig(Action-base)时,XR Rig 使用的输入接口为InputSystem.

在Window->Analysis->InputDebugger 中可以看到InputSystem中的布局

Input Layout

在之前的 XR SDK输入子系统中我们在加载子系统时注册了自己设备的InputLayouts.

在InputDebug面板中 Layouts -> SpecificDevice ->TrackedDevices 下可以看到自定义注册的手柄布局

input layout

通过InputSystem获取输入的方式

InputSystem使用方式参考官方demo演示
1.创建InputActionAsset后生成通过对应的C#脚本,可以在Unity中直接New,添加对应的控制器响应(通过代码添加输入响应)
2.不需要创建InputActionAsset,直接在脚本中添加InputAction字段,通过在面板中选择接收的Action,在代码中直接对InputAction字段进行响应(无需创建InputActionAsset)
3.创建InputActionAsset,通过添加PlayerInput,可以将多个输入事件的响应通过拖拽绑定在一个PlayerInput中(可以自定义输入响应范围)
4.不需要创建InputActionAsset,直接在代码中指定读取输入设备中的键值,通过Update检测值变化做对应响应(类似于InputManager中的GetKeyDown())
Action,在代码中直接对InputAction字段进行响应(无需创建InputActionAsset)
3.创建InputActionAsset,通过添加PlayerInput,可以将多个输入事件的响应通过拖拽绑定在一个PlayerInput中(可以自定义输入响应范围)
4.不需要创建InputActionAsset,直接在代码中指定读取输入设备中的键值,通过Update检测值变化做对应响应(类似于InputManager中的GetKeyDown())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值