上传YomovSDK
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 632a91c30693a654d80b70b28e764d3d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,134 @@
|
||||
using System.Runtime.InteropServices;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.XR.OpenXR.NativeTypes;
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows interaction with the Performance settings API,
|
||||
/// which allows the application to provide hints to the runtime about the performance characteristics of the application,
|
||||
/// and to receive notifications from the runtime about changes in performance state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Refer to [XR performance settings](xref:openxr-performance-settings) for additional information.
|
||||
/// </remarks>
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(
|
||||
UiName = "XR Performance Settings",
|
||||
Desc = "Optional extension for providing performance hints to runtime and receive notifications aobut device performance changes.",
|
||||
Company = "Unity",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/performance-settings.html",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "1.0.0",
|
||||
FeatureId = featureId
|
||||
)]
|
||||
#endif
|
||||
public class XrPerformanceSettingsFeature : OpenXRFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.extension.performance_settings";
|
||||
|
||||
/// <summary>
|
||||
/// Name of the OpenXR extension for performance settings.
|
||||
/// </summary>
|
||||
public const string extensionString = "XR_EXT_performance_settings";
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to this event to receive performance change notifications from the OpenXR runtime.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Refer to [Performance notifications](xref:openxr-performance-settings#performance-settings-notifications) for additional information.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <para>
|
||||
/// Example of subscribing to the event and handling the performance change notification:
|
||||
/// </para>
|
||||
/// <code lang="cs">
|
||||
/// <![CDATA[
|
||||
/// XrPerformanceSettingsFeature.OnXrPerformanceChangeNotification += OnGPUPerformanceChange;
|
||||
/// ]]>
|
||||
/// </code>
|
||||
/// <para>
|
||||
/// Example of handling the performance change notification:
|
||||
/// </para>
|
||||
/// <code lang="cs">
|
||||
/// <![CDATA[
|
||||
/// void OnGPUPerformanceChange(PerformanceChangeNotification notification)
|
||||
/// {
|
||||
/// if (notification.domain != Domain.GPU)
|
||||
/// {
|
||||
/// return;
|
||||
/// }
|
||||
///
|
||||
/// if (notification.toLevel == PerformanceNotificationLevel.Normal)
|
||||
/// {
|
||||
/// // Performance has improved
|
||||
/// UseDefaultQuality();
|
||||
/// }
|
||||
/// else
|
||||
/// {
|
||||
/// // Performance has degraded
|
||||
/// UseReducedQuality();
|
||||
/// }
|
||||
/// }
|
||||
/// ]]>
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static event UnityAction<PerformanceChangeNotification> OnXrPerformanceChangeNotification;
|
||||
|
||||
/// <summary>
|
||||
/// Provides the OpenXR runtime with the desired performance level to be used for the specified domain.
|
||||
/// </summary>
|
||||
/// <param name="domain">Domain for which the performance hit will be sent.</param>
|
||||
/// <param name="level">Desired performance asked by the application.</param>
|
||||
/// <returns>True if the performance level hint was successfully set, false otherwise.</returns>
|
||||
/// <remarks>
|
||||
/// Refer to [Performance level hints](xref: openxr-performance-settings#performance-settings-level-hints) for additional information.
|
||||
/// </remarks>
|
||||
public static bool SetPerformanceLevelHint(PerformanceDomain domain, PerformanceLevelHint level)
|
||||
{
|
||||
if (OpenXRRuntime.IsExtensionEnabled(extensionString))
|
||||
{
|
||||
return NativeApi.xr_performance_settings_setPerformanceLevel(domain, level);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When an instance of the Performance setting feature is created, it allows us to confirm that the instance has been created, that the extension is enabled
|
||||
/// and we have successfully registed the performance notification callback
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">XR Session Instance</param>
|
||||
/// <returns>True if the instance has successfully been created. Otherwise it returns false.</returns>
|
||||
protected internal override bool OnInstanceCreate(ulong xrInstance)
|
||||
{
|
||||
return base.OnInstanceCreate(xrInstance) &&
|
||||
OpenXRRuntime.IsExtensionEnabled(extensionString) &&
|
||||
NativeApi.xr_performance_settings_setEventCallback(OnXrPerformanceNotificationCallback);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(NativeApi.XrPerformanceNotificationDelegate))]
|
||||
private static void OnXrPerformanceNotificationCallback(PerformanceChangeNotification notification)
|
||||
{
|
||||
OnXrPerformanceChangeNotification?.Invoke(notification);
|
||||
}
|
||||
|
||||
internal static class NativeApi
|
||||
{
|
||||
internal delegate void XrPerformanceNotificationDelegate(PerformanceChangeNotification notification);
|
||||
|
||||
[DllImport("UnityOpenXR")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool xr_performance_settings_setEventCallback(XrPerformanceNotificationDelegate callback);
|
||||
|
||||
[DllImport("UnityOpenXR")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool xr_performance_settings_setPerformanceLevel(PerformanceDomain domain, PerformanceLevelHint level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b213d3e3c7f3109449eb46a4c8ee42f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,133 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Hardware system.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the members of this enumeration when setting a performance hint with <see cref="XRPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain, PerformanceLevelHint)"/>.
|
||||
///
|
||||
/// Members of this enumeration are reported in the events dispatched by <see cref="XRPerformanceSettingsFeature.UnityAction{PerformanceChangeNotification} OnXrPerformanceChangeNotification"/>.
|
||||
/// </remarks>
|
||||
public enum PerformanceDomain
|
||||
{
|
||||
/// <summary>
|
||||
/// CPU hardware domain.
|
||||
/// </summary>
|
||||
Cpu = 1,
|
||||
/// <summary>
|
||||
/// Graphics hardware domain.
|
||||
/// </summary>
|
||||
Gpu = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specific context of the hardware domain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Members of this enumeration are reported in the events dispatched by
|
||||
/// <see cref="XRPerformanceSettingsFeature.UnityAction{PerformanceChangeNotification} OnXrPerformanceChangeNotification"/>.
|
||||
/// </remarks>
|
||||
public enum PerformanceSubDomain
|
||||
{
|
||||
/// <summary>
|
||||
/// Composition of submitted layers.
|
||||
/// </summary>
|
||||
Compositing = 1,
|
||||
/// <summary>
|
||||
/// Graphics rendering and frame submission.
|
||||
/// </summary>
|
||||
Rendering = 2,
|
||||
/// <summary>
|
||||
/// Physical device temperature.
|
||||
/// </summary>
|
||||
Thermal = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performance level of the platform.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use the members of this enumeration when setting a performance hint with
|
||||
/// <see cref="XRPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain, PerformanceLevelHint)"/>.
|
||||
/// </remarks>
|
||||
public enum PerformanceLevelHint
|
||||
{
|
||||
/// <summary>
|
||||
/// The application will enter a non-XR section,
|
||||
/// so power savings will be prioritized over all.
|
||||
/// </summary>
|
||||
PowerSavings = 0,
|
||||
/// <summary>
|
||||
/// The application will enter a low and stable complexity section,
|
||||
/// so power usage will be prioritized over late frame rendering.
|
||||
/// </summary>
|
||||
SustainedLow = 25,
|
||||
/// <summary>
|
||||
/// The application will enter a high or dynamic complexity section,
|
||||
/// so the application performance will be prioritized within sustainable thermal ranges.
|
||||
/// </summary>
|
||||
SustainedHigh = 50,
|
||||
/// <summary>
|
||||
/// The application will enter a very high complexity section,
|
||||
/// so performance will be boosted over sustainable thermal ranges.
|
||||
/// Note that usage of this level hint is recommended for short durations (less than 30 seconds).
|
||||
/// </summary>
|
||||
Boost = 75
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notification level about the performance state of the platform.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Members of this enumeration are reported in the events dispatched by
|
||||
/// <see cref="XRPerformanceSettingsFeature.UnityAction{PerformanceChangeNotification} OnXrPerformanceChangeNotification"/>.
|
||||
/// </remarks>
|
||||
public enum PerformanceNotificationLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// Performance is in nominal status.
|
||||
/// </summary>
|
||||
Normal = 0,
|
||||
/// <summary>
|
||||
/// Early warning for potential performance degradation.
|
||||
/// </summary>
|
||||
Warning = 25,
|
||||
/// <summary>
|
||||
/// Performance is degraded.
|
||||
/// </summary>
|
||||
Impaired = 75
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notification about the performance state of the platform.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This struct is part of the events dispatched by
|
||||
/// <see cref="XRPerformanceSettingsFeature.UnityAction{PerformanceChangeNotification} OnXrPerformanceChangeNotification"/>.
|
||||
/// </remarks>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PerformanceChangeNotification
|
||||
{
|
||||
/// <summary>
|
||||
/// Platform domain that the notification is about.
|
||||
/// </summary>
|
||||
public PerformanceDomain domain;
|
||||
/// <summary>
|
||||
/// Platform subdomain that the notification is about.
|
||||
/// </summary>
|
||||
public PerformanceSubDomain subDomain;
|
||||
/// <summary>
|
||||
/// Previous performance level.
|
||||
/// </summary>
|
||||
public PerformanceNotificationLevel fromLevel;
|
||||
/// <summary>
|
||||
/// Upcoming performance level.
|
||||
/// </summary>
|
||||
public PerformanceNotificationLevel toLevel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48fee7f780ee00c44bc696d37673aec9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRFeature"/> enables the use of foveated rendering in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Foveated Rendering",
|
||||
BuildTargetGroups = new []{BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Add foveated rendering.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/foveatedrendering.html",
|
||||
OpenxrExtensionStrings = "XR_UNITY_foveation XR_FB_foveation XR_FB_foveation_configuration XR_FB_swapchain_update_state XR_FB_foveation_vulkan XR_META_foveation_eye_tracked XR_META_vulkan_swapchain_create_info",
|
||||
Version = "1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Feature,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class FoveatedRenderingFeature : OpenXRFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.foveatedrendering";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// If using BiRP, the feature must know not to use the newer API for FSR/FDM
|
||||
Internal_Unity_SetUseFoveatedRenderingLegacyMode(GraphicsSettings.defaultRenderPipeline == null);
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected internal override IntPtr HookGetInstanceProcAddr(IntPtr func)
|
||||
{
|
||||
return Internal_Unity_intercept_xrGetInstanceProcAddr(func);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
private const string Library = "UnityOpenXR";
|
||||
|
||||
[DllImport(Library, EntryPoint = "UnityFoveation_intercept_xrGetInstanceProcAddr")]
|
||||
private static extern IntPtr Internal_Unity_intercept_xrGetInstanceProcAddr(IntPtr func);
|
||||
|
||||
[DllImport(Library, EntryPoint = "UnityFoveation_SetUseFoveatedRenderingLegacyMode")]
|
||||
private static extern void Internal_Unity_SetUseFoveatedRenderingLegacyMode([MarshalAs(UnmanagedType.I1)] bool value);
|
||||
|
||||
[DllImport(Library, EntryPoint = "UnityFoveation_GetUseFoveatedRenderingLegacyMode")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool Internal_Unity_GetUseFoveatedRenderingLegacyMode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6a75d1f5ff90154ea2a8e58222a1f59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa266ef62a5d4ede92a5c128da19498c
|
||||
timeCreated: 1606858557
|
||||
@@ -0,0 +1,517 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of DPad feature in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "D-Pad Binding",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Add DPad feature support and if enabled, extra dpad paths will be added to any controller profiles with a thumbstick or trackpad.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/dpadinteraction.html",
|
||||
OpenxrExtensionStrings = "XR_KHR_binding_modification XR_EXT_dpad_binding",
|
||||
Version = "0.0.1",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class DPadInteraction : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.dpadinteraction";
|
||||
|
||||
/// <summary>
|
||||
/// A flag to mark this DPad feature is additive.
|
||||
/// </summary>
|
||||
internal override bool IsAdditive => true;
|
||||
|
||||
/// <summary>
|
||||
/// a number in the half-open range (0, 1] representing the force value threshold at or above which ≥ a dpad input will transition from inactive to active.
|
||||
/// </summary>
|
||||
public float forceThresholdLeft = 0.5f;
|
||||
/// <summary>
|
||||
/// a number in the half-open range (0, 1] representing the force value threshold strictly below which less than a dpad input will transition from active to inactive.
|
||||
/// </summary>
|
||||
public float forceThresholdReleaseLeft = 0.4f;
|
||||
/// <summary>
|
||||
/// the radius in the input value space, of a logically circular region in the center of the input, in the range (0, 1).
|
||||
/// </summary>
|
||||
public float centerRegionLeft = 0.5f;
|
||||
/// <summary>
|
||||
/// indicates the angle in radians of each direction region and is a value in the half-open range (0, π].
|
||||
/// </summary>
|
||||
public float wedgeAngleLeft = (float)(0.5f * Math.PI);
|
||||
/// <summary>
|
||||
/// indicates that the implementation will latch the first region that is activated and continue to indicate that the binding for that region is true until the user releases the input underlying the virtual dpad.
|
||||
/// </summary>
|
||||
public bool isStickyLeft = false;
|
||||
|
||||
/// <summary>
|
||||
/// a number in the half-open range (0, 1] representing the force value threshold at or above which ≥ a dpad input will transition from inactive to active.
|
||||
/// </summary>
|
||||
public float forceThresholdRight = 0.5f;
|
||||
/// <summary>
|
||||
/// a number in the half-open range (0, 1] representing the force value threshold strictly below which less than a dpad input will transition from active to inactive.
|
||||
/// </summary>
|
||||
public float forceThresholdReleaseRight = 0.4f;
|
||||
/// <summary>
|
||||
/// the radius in the input value space, of a logically circular region in the center of the input, in the range (0, 1).
|
||||
/// </summary>
|
||||
public float centerRegionRight = 0.5f;
|
||||
/// <summary>
|
||||
/// indicates the angle in radians of each direction region and is a value in the half-open range [0, π].
|
||||
/// </summary>
|
||||
public float wedgeAngleRight = (float)(0.5f * Math.PI);
|
||||
/// <summary>
|
||||
/// indicates that the implementation will latch the first region that is activated and continue to indicate that the binding for that region is true until the user releases the input underlying the virtual dpad.
|
||||
/// </summary>
|
||||
public bool isStickyRight = false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal class DpadControlEditorWindow : EditorWindow
|
||||
{
|
||||
private Object feature;
|
||||
private Editor featureEditor;
|
||||
|
||||
public static EditorWindow Create(Object feature)
|
||||
{
|
||||
var window = EditorWindow.GetWindow<DpadControlEditorWindow>(true, "Dpad Interaction Binding Setting", true);
|
||||
window.feature = feature;
|
||||
window.featureEditor = Editor.CreateEditor(feature);
|
||||
return window;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
featureEditor.OnInspectorGUI();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// A dpad-like interaction feature that allows the application to bind one or more digital actions to a trackpad or thumbstick as though it were a dpad. <a href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XrInteractionProfileDpadBindingEXT">XrInteractionProfileDpadBindingEXT</a>
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "D-Pad Binding (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class DPad : XRController
|
||||
{
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.thumbstickDpadUp"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl thumbstickDpadUp { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.thumbstickDpadDown"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl thumbstickDpadDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.thumbstickDpadLeft"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl thumbstickDpadLeft { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.thumbstickDpadRight"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl thumbstickDpadRight { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.trackpadDpadUp"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl trackpadDpadUp { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.trackpadDpadDown"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl trackpadDpadDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteractionP.trackpadDpadLeft"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl trackpadDpadLeft { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.trackpadDpadRight"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl trackpadDpadRight { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="DPadInteraction.trackpadDpadCenter"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl()]
|
||||
public ButtonControl trackpadDpadCenter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
thumbstickDpadUp = GetChildControl<ButtonControl>("thumbstickDpadUp");
|
||||
thumbstickDpadDown = GetChildControl<ButtonControl>("thumbstickDpadDown");
|
||||
thumbstickDpadLeft = GetChildControl<ButtonControl>("thumbstickDpadLeft");
|
||||
thumbstickDpadRight = GetChildControl<ButtonControl>("thumbstickDpadRight");
|
||||
trackpadDpadUp = GetChildControl<ButtonControl>("trackpadDpadUp");
|
||||
trackpadDpadDown = GetChildControl<ButtonControl>("trackpadDpadDown");
|
||||
trackpadDpadLeft = GetChildControl<ButtonControl>("trackpadDpadLeft");
|
||||
trackpadDpadRight = GetChildControl<ButtonControl>("trackpadDpadRight");
|
||||
trackpadDpadCenter = GetChildControl<ButtonControl>("trackpadDpadCenter");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../thumbstick/dpad_up' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickDpadUp = "/input/thumbstick/dpad_up";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../thumbstick/dpad_down' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickDpadDown = "/input/thumbstick/dpad_down";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../thumbstick/dpad_left' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickDpadLeft = "/input/thumbstick/dpad_left";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../thumbstick/dpad_right' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickDpadRight = "/input/thumbstick/dpad_right";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../trackpad/dpad_up' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadDpadUp = "/input/trackpad/dpad_up";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../trackpad/dpad_down' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadDpadDown = "/input/trackpad/dpad_down";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../trackpad/dpad_left' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadDpadLeft = "/input/trackpad/dpad_left";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../trackpad/dpad_right' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadDpadRight = "/input/trackpad/dpad_right";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../trackpad/dpad_center' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadDpadCenter = "/input/trackpad/dpad_center";
|
||||
|
||||
/// <summary>
|
||||
/// A unique string for dpad feature
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/unity/dpad";
|
||||
|
||||
private const string kDeviceLocalizedName = "DPad Interaction OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// The OpenXR Extension strings. This is used by OpenXR to check if this extension is available or enabled.
|
||||
/// </summary>
|
||||
public string[] extensionStrings = { "XR_KHR_binding_modification", "XR_EXT_dpad_binding" };
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected internal override void GetValidationChecks(List<OpenXRFeature.ValidationRule> results, BuildTargetGroup target)
|
||||
{
|
||||
results.Add( new ValidationRule(this){
|
||||
message = "Additive Interaction feature requires a valid controller profile with thumbstick or trackpad selected within Interaction Profiles.",
|
||||
error = true,
|
||||
errorEnteringPlaymode = true,
|
||||
checkPredicate = () =>
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(target);
|
||||
if (null == settings)
|
||||
return false;
|
||||
|
||||
bool dpadFeatureEnabled = false;
|
||||
bool otherNonAdditiveInteractionFeatureEnabled = false;
|
||||
foreach (var feature in settings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
if (feature is DPadInteraction)
|
||||
dpadFeatureEnabled = true;
|
||||
else if (!(feature as OpenXRInteractionFeature).IsAdditive && !(feature is EyeGazeInteraction))
|
||||
otherNonAdditiveInteractionFeatureEnabled = true;
|
||||
}
|
||||
}
|
||||
return dpadFeatureEnabled && otherNonAdditiveInteractionFeatureEnabled;
|
||||
},
|
||||
fixIt = () => SettingsService.OpenProjectSettings("Project/XR Plug-in Management/OpenXR"),
|
||||
fixItAutomatic = false,
|
||||
fixItMessage = "Open Project Settings to select one or more non Additive interaction profiles."
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires dpad related exts
|
||||
foreach (var ext in extensionStrings)
|
||||
{
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(ext))
|
||||
return false;
|
||||
}
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="DPad"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(DPad),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="DPad"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(DPad));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string for registering Dpad in InputSystem.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(DPad);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "dpadinteraction",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickDpadUp",
|
||||
localizedName = " Thumbstick Dpad Up",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickDpadUp,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickDpadDown",
|
||||
localizedName = "Thumbstick Dpad Down",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickDpadDown,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickDpadLeft",
|
||||
localizedName = "Thumbstick Dpad Left",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickDpadLeft,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickDpadRight",
|
||||
localizedName = "Thumbstick Dpad Right",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickDpadRight,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadDpadUp",
|
||||
localizedName = "Trackpad Dpad Up",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadDpadUp,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadDpadDown",
|
||||
localizedName = "Trackpad Dpad Down",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadDpadDown,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadDpadLeft",
|
||||
localizedName = "Trackpad Dpad Left",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadDpadLeft,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadDpadRight",
|
||||
localizedName = "Trackpad Dpad Right",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadDpadRight,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadDpadCenter",
|
||||
localizedName = "Trackpad Dpad Center",
|
||||
type = ActionType.Binary,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadDpadCenter,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
|
||||
//Process additive actions: add additional supported additive actions to the existing controller profiles
|
||||
internal override void AddAdditiveActions(List<OpenXRInteractionFeature.ActionMapConfig> actionMaps, ActionMapConfig additiveMap)
|
||||
{
|
||||
foreach (var actionMap in actionMaps)
|
||||
{
|
||||
//valid userPath is user/hand/left or user/hand/right
|
||||
var validUserPath = actionMap.deviceInfos.Where(d => d.userPath != null && ((String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.leftHand) == 0) ||
|
||||
(String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.rightHand) == 0)));
|
||||
if (!validUserPath.Any())
|
||||
continue;
|
||||
|
||||
//check if interaction profile has thumbstick and/or trackpad
|
||||
bool hasTrackPad = false;
|
||||
bool hasThumbstick = false;
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (!hasTrackPad)
|
||||
{
|
||||
var withTrackpad = action.bindings.FirstOrDefault(b => b.interactionPath.Contains("trackpad"));
|
||||
if (withTrackpad != null)
|
||||
hasTrackPad = true;
|
||||
}
|
||||
if (!hasThumbstick)
|
||||
{
|
||||
var withThumbstick = action.bindings.FirstOrDefault(b => b.interactionPath.Contains("thumbstick"));
|
||||
if (withThumbstick != null)
|
||||
hasThumbstick = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var additiveAction in additiveMap.actions.Where(a => a.isAdditive))
|
||||
{
|
||||
if ((hasTrackPad && additiveAction.name.StartsWith("trackpad")) || (hasThumbstick && additiveAction.name.StartsWith("thumbstick")))
|
||||
actionMap.actions.Add(additiveAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c5b5af5107e35a43818d5411328bfc3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,210 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of eye gaze interaction profiles in OpenXR. It enables <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_eye_gaze_interaction">XR_EXT_eye_gaze_interaction</a> in the underlying runtime.
|
||||
/// This creates a new <see cref="InputDevice"/> with the <see cref="InputDeviceCharacteristics.EyeTracking"/> characteristic. This new device has both <see cref="EyeTrackingUsages.gazePosition"/> and <see cref="EyeTrackingUsages.gazeRotation"/> input features, as well as <see cref="CommonUsages.isTracked"/> and <see cref="CommonUsages.trackingState"/> usages to determine if the gaze is available.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Eye Gaze Interaction Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.WSA, BuildTargetGroup.Standalone, BuildTargetGroup.Android },
|
||||
Company = "Unity",
|
||||
Desc = "Support for enabling the eye tracking interaction profile. Will register the controller map for eye tracking if enabled.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/eyegazeinteraction.html",
|
||||
Version = "0.0.1",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class EyeGazeInteraction : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.eyetracking";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_eye_gaze_input">Eye Gaze Interaction Profile</a>. Enabled through <see cref="EyeGazeInteraction"/>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Eye Gaze (OpenXR)", isGenericTypeOfDevice = true)]
|
||||
public class EyeGazeDevice : OpenXRDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> representing the <see cref="EyeGazeInteraction.pose"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, usages = new[] { "Device", "gaze" })]
|
||||
public PoseControl pose { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
pose = GetChildControl<PoseControl>("pose");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OpenXR constant that is used to reference an eye tracking supported input device. See <see href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#semantic-path-user">OpenXR Specification 6.3.1</see> for more information on user paths.
|
||||
/// </summary>
|
||||
private const string userPath = "/user/eyes_ext";
|
||||
|
||||
/// <summary>The interaction profile string used to reference the eye gaze input device.</summary>
|
||||
private const string profile = "/interaction_profiles/ext/eye_gaze_interaction";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/gaze_ext/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
private const string pose = "/input/gaze_ext/pose";
|
||||
|
||||
private const string kDeviceLocalizedName = "Eye Tracking OpenXR";
|
||||
|
||||
/// <summary>The OpenXR Extension string. This is used by OpenXR to check if this extension is available or enabled. See <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_eye_gaze_interaction">eye gaze interaction extension</a> documentation for more information on this OpenXR extension.</summary>
|
||||
public const string extensionString = "XR_EXT_eye_gaze_interaction";
|
||||
|
||||
private const string layoutName = "EyeGaze";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected internal override void GetValidationChecks(List<OpenXRFeature.ValidationRule> results, BuildTargetGroup target)
|
||||
{
|
||||
if (target == BuildTargetGroup.WSA)
|
||||
{
|
||||
results.Add(new ValidationRule(this){
|
||||
message = "Eye Gaze support requires the Gaze Input capability.",
|
||||
error = false,
|
||||
checkPredicate = () => PlayerSettings.WSA.GetCapability(PlayerSettings.WSACapability.GazeInput),
|
||||
fixIt = () => PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.GazeInput, true)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires the eye tracking extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(extensionString))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="EyeGazeDevice"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(EyeGazeDevice),
|
||||
layoutName,
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="EyeGazeDevice"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(layoutName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return interaction profile type. EyeGaze profile is Device type.
|
||||
/// </summary>
|
||||
/// <returns>Interaction profile type.</returns>
|
||||
protected override InteractionProfileType GetInteractionProfileType()
|
||||
{
|
||||
return typeof(EyeGazeDevice).IsSubclassOf(typeof(XRController)) ? InteractionProfileType.XRController : InteractionProfileType.Device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layer out string used for registering device EyeGaze in InputSystem.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return layoutName;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "eyegaze",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.EyeTracking | InputDeviceCharacteristics.HeadMounted,
|
||||
userPath = userPath
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pose",
|
||||
localizedName = "Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device",
|
||||
"gaze"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pose,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tags that can be used with <see cref="InputDevice.TryGetFeatureValue"/> to get eye tracking related input features. See <see cref="CommonUsages"/> for additional usages.
|
||||
/// </summary>
|
||||
public static class EyeTrackingUsages
|
||||
{
|
||||
/// <summary>The origin position for the gaze. The gaze represents where a user is looking, and <see cref="gazePosition"/> represents the starting location, close to the eyes, from which to project a gaze ray from.</summary>
|
||||
public static InputFeatureUsage<Vector3> gazePosition = new InputFeatureUsage<Vector3>("gazePosition");
|
||||
/// <summary>The orientation of the gaze, such that the direction of the gaze is the same as <see cref="Vector3.forward "/> * gazeRotation. Use with <see cref="gazePosition"/> to create a gaze ray.</summary>
|
||||
public static InputFeatureUsage<Quaternion> gazeRotation = new InputFeatureUsage<Quaternion>("gazeRotation");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3cf79659a011bd419c7a2a30eb74e9a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,558 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of HP Reverb G2 Controller interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "HP Reverb G2 Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the HP Reverb G2 Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/hpreverbg2controllerprofile.html",
|
||||
OpenxrExtensionStrings = "XR_EXT_hp_mixed_reality_controller",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class HPReverbG2ControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.hpreverb";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the <a href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hp_mixed_reality_controller">HP Reverb G2 Controller</a>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "HP Reverb G2 Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class ReverbG2Controller : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HPReverbG2ControllerProfile.buttonA"/> <see cref="HPReverbG2ControllerProfile.buttonX"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "A", "X", "buttonA", "buttonX" }, usage = "PrimaryButton")]
|
||||
public ButtonControl primaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HPReverbG2ControllerProfile.buttonB"/> <see cref="HPReverbG2ControllerProfile.buttonY"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "B", "Y", "buttonB", "buttonY" }, usage = "SecondaryButton")]
|
||||
public ButtonControl secondaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HPReverbG2ControllerProfile.menu"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menubutton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="HPReverbG2ControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HPReverbG2ControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="HPReverbG2ControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HPReverbG2ControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexButton", "indexTouched", "triggerbutton" }, usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="HPReverbG2ControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "Joystick" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl thumbstick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HPReverbG2ControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadPressed", "thumbstickClick", "joystickClicked" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl thumbstickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HPReverbG2ControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents information from the <see cref="HPReverbG2ControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 29)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for back compatibility with the XRSDK layouts. This represents the bit flag set indicating what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the device position. This is both the grip and the pointer position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 36, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. This is both the grip and the pointer rotation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 48, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 96)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 108, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="HPReverbG2ControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="OpenXRDevice"/>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
thumbstick = GetChildControl<StickControl>("thumbstick");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The interaction profile string used to reference the <a href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hp_mixed_reality_controller">HP Reverb G2 Controller</a>.</summary>
|
||||
public const string profile = "/interaction_profiles/hp/mixed_reality_controller";
|
||||
|
||||
// Available Bindings
|
||||
// Left Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonX = "/input/x/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonY = "/input/y/click";
|
||||
|
||||
// Right Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonA = "/input/a/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '..."/input/b/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonB = "/input/b/click";
|
||||
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/squeeze/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/thumbstick' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "HP Reverb G2 Controller OpenXR";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires extension to enable
|
||||
if (!OpenXRRuntime.IsExtensionEnabled("XR_EXT_hp_mixed_reality_controller"))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="ReverbG2Controller"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(ReverbG2Controller),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="ReverbG2Controller"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(ReverbG2Controller));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(ReverbG2Controller);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "hpreverbg2controller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "HP",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
//A / X Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryButton",
|
||||
localizedName = "Primary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonX,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonA,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryButton",
|
||||
localizedName = "Secondary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonY,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonB,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstick",
|
||||
localizedName = "Thumbstick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickClicked",
|
||||
localizedName = "Thumbstick Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5315f812f023cf4ebf26f7e5d2d70f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,521 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of HTC Vive Controllers interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "HTC Vive Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the HTC Vive Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/htcvivecontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class HTCViveControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.htcvive";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_htc_vive_controller_profile">HTC Vive Controller</a>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "HTC Vive Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class ViveController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the HTC Vive Controller Profile select OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Secondary", "selectbutton" }, usage = "SystemButton")]
|
||||
public ButtonControl select { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents information from the <see cref="HTCViveControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HTCViveControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HTCViveControllerProfile.menu"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menubutton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents information from the <see cref="HTCViveControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "triggeraxis", usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HTCViveControllerProfile.triggerClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "triggerbutton", usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents information from the <see cref="HTCViveControllerProfile.trackpad"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "touchpadaxes", "touchpad" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl trackpad { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HTCViveControllerProfile.trackpadClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystickorpadpressed", "touchpadpressed" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl trackpadClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents information from the <see cref="HTCViveControllerProfile.trackpadTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystickorpadtouched", "touchpadtouched" }, usage = "Primary2DAxisTouch")]
|
||||
public ButtonControl trackpadTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents information from the <see cref="HTCViveControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents information from the <see cref="HTCViveControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 26)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for back compatibility with the XRSDK layouts. This represents the bit flag set indicating what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 28)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the device position. For the Oculus Touch device, this is both the grip and the pointer position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. For the Oculus Touch device, this is both the grip and the pointer rotation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 44, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 92)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 104, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="HTCViveControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="OpenXRDevice"/>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
select = GetChildControl<ButtonControl>("select");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
trackpad = GetChildControl<StickControl>("trackpad");
|
||||
trackpadClicked = GetChildControl<ButtonControl>("trackpadClicked");
|
||||
trackpadTouched = GetChildControl<ButtonControl>("trackpadTouched");
|
||||
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The interaction profile string used to reference the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_htc_vive_controller_profile">HTC Vive Controller</a>.</summary>
|
||||
public const string profile = "/interaction_profiles/htc/vive_controller";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string system = "/input/system/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/squeeze/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerClick = "/input/trigger/click";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/trackpad' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpad = "/input/trackpad";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trackpad/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpadClick = "/input/trackpad/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trackpad/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpadTouch = "/input/trackpad/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "HTC Vive Controller OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="ViveController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(ViveController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="ViveController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(ViveController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(ViveController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "htcvivecontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "HTC",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "select",
|
||||
localizedName = "Select",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SystemButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = system,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpad",
|
||||
localizedName = "Trackpad",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpad,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadTouched",
|
||||
localizedName = "Trackpad Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadClicked",
|
||||
localizedName = "Trackpad Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 274c02963f889a64e90bc2e596e21d13
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,339 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of hand common poses profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Hand Interaction Poses",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Add hand common interaction poses feature, if enabled, four additional commonly used poses will be supported.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/handcommonposesinteraction.html",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "0.0.1",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class HandCommonPosesInteraction : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.handinteractionposes";
|
||||
|
||||
/// <summary>
|
||||
/// A flag to mark this hand interaction feature is potentially additive.
|
||||
/// </summary>
|
||||
internal override bool IsAdditive => true;
|
||||
|
||||
/// <summary>
|
||||
/// An interaction feature that supports commonly used hand poses for hand interactions across motion controller and hand tracking devices.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Hand Interaction Poses (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" }, isGenericTypeOfDevice = true)]
|
||||
public class HandInteractionPoses : OpenXRDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandCommonPosesInteraction.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandCommonPosesInteraction.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandCommonPosesInteraction.poke"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0)]
|
||||
public PoseControl pokePose { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandCommonPosesInteraction.pinch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0)]
|
||||
public PoseControl pinchPose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
pokePose = GetChildControl<PoseControl>("pokePose");
|
||||
pinchPose = GetChildControl<PoseControl>("pinchPose");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference Hand Common Poses feature.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/unity/hand_interaction_poses";
|
||||
|
||||
// Available Bindings
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/poke_ext/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string poke = "/input/poke_ext/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/pinch_ext/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pinch = "/input/pinch_ext/pose";
|
||||
|
||||
private const string kDeviceLocalizedName = "Hand Interaction Poses OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// The OpenXR Extension string. This is used by OpenXR to check if this extension is available or enabled.
|
||||
/// </summary>
|
||||
public const string extensionString = "XR_EXT_hand_interaction";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected internal override void GetValidationChecks(List<OpenXRFeature.ValidationRule> results, BuildTargetGroup target)
|
||||
{
|
||||
results.Add( new ValidationRule(this){
|
||||
message = "Additive Interaction feature requires a valid controller or hand interaction profile selected within Interaction Profiles.",
|
||||
error = true,
|
||||
errorEnteringPlaymode = true,
|
||||
checkPredicate = () =>
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(target);
|
||||
if (null == settings)
|
||||
return false;
|
||||
|
||||
bool handCommonPosesFeatureEnabled = false;
|
||||
bool otherNonAdditiveInteractionFeatureEnabled = false;
|
||||
foreach (var feature in settings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
if (feature is HandCommonPosesInteraction)
|
||||
handCommonPosesFeatureEnabled = true;
|
||||
else if (!(feature as OpenXRInteractionFeature).IsAdditive && !(feature is EyeGazeInteraction))
|
||||
otherNonAdditiveInteractionFeatureEnabled = true;
|
||||
}
|
||||
}
|
||||
return handCommonPosesFeatureEnabled && otherNonAdditiveInteractionFeatureEnabled;
|
||||
},
|
||||
fixIt = () => SettingsService.OpenProjectSettings("Project/XR Plug-in Management/OpenXR"),
|
||||
fixItAutomatic = false,
|
||||
fixItMessage = "Open Project Settings to select one or more non Additive interaction profiles."
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires hand tracking extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(extensionString))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="HandInteractionPoses"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(HandInteractionPoses),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="HandInteractionPoses"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(HandInteractionPoses));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return Interaction profile type. Hand common poses profile is Device type.
|
||||
/// </summary>
|
||||
/// <returns>Interaction profile type.</returns>
|
||||
protected override InteractionProfileType GetInteractionProfileType()
|
||||
{
|
||||
return typeof(HandInteractionPoses).IsSubclassOf(typeof(XRController)) ? InteractionProfileType.XRController : InteractionProfileType.Device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used to register device in InputSystem.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(HandInteractionPoses);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "handinteractionposes",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
//Poke Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PokePose",
|
||||
localizedName = "Poke Pose",
|
||||
type = ActionType.Pose,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = poke,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
},
|
||||
//Pinch Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PinchPose",
|
||||
localizedName = "Pinch Pose",
|
||||
type = ActionType.Pose,
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pinch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
},
|
||||
isAdditive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
|
||||
//Process additive actions: add additional supported additive actions to existing controller or hand interaction profiles
|
||||
internal override void AddAdditiveActions(List<OpenXRInteractionFeature.ActionMapConfig> actionMaps, ActionMapConfig additiveMap)
|
||||
{
|
||||
foreach (var actionMap in actionMaps)
|
||||
{
|
||||
//valid userPath is user/hand/left or user/hand/right
|
||||
var validUserPath = actionMap.deviceInfos.Where(d => d.userPath != null && ((String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.leftHand) == 0) ||
|
||||
(String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.rightHand) == 0)));
|
||||
|
||||
if (validUserPath.Any())
|
||||
{
|
||||
foreach (var additiveAction in additiveMap.actions.Where(a => a.isAdditive))
|
||||
{
|
||||
bool duplicateFound = false;
|
||||
var poseActions = actionMap.actions.Where(m => m.type == ActionType.Pose).Distinct().ToList();
|
||||
foreach (var poseAction in poseActions)
|
||||
{
|
||||
if ((poseAction.bindings.Where(b => b.interactionPath != null && (String.CompareOrdinal(b.interactionPath, additiveAction.bindings[0].interactionPath) == 0))).Any())
|
||||
{
|
||||
poseAction.isAdditive = true;
|
||||
duplicateFound = true;
|
||||
}
|
||||
}
|
||||
if (!duplicateFound)
|
||||
actionMap.actions.Add(additiveAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a24be4b5ebfe5f4d8ed1de9b25cb7aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,576 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of New Hand interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Hand Interaction Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Add hand interaction profile for hand tracking input device.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/handinteractionprofile.html",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class HandInteractionProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.handinteraction";
|
||||
|
||||
/// <summary>
|
||||
/// A new interaction profile for hand tracking input device to provide actions through the OpenXR action system.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Hand Interaction (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class HandInteraction : XRController
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandInteractionProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandInteractionProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandInteractionProfile.poke"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, usage = "Poke")]
|
||||
public PoseControl pokePose { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="HandInteractionProfile.pinch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, usage = "Pinch")]
|
||||
public PoseControl pinchPose { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="HandInteractionProfile.pinchValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PinchValue")]
|
||||
public AxisControl pinchValue { get; private set; }
|
||||
/// <summary>
|
||||
/// An [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.pinchValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PinchTouched")]
|
||||
public ButtonControl pinchTouched { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.pinchReady"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PinchReady")]
|
||||
public ButtonControl pinchReady { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="HandInteractionProfile.pointerActivateValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PointerActivateValue")]
|
||||
public AxisControl pointerActivateValue { get; private set; }
|
||||
/// <summary>
|
||||
/// An [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.pointerActivateValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PointerActivated")]
|
||||
public ButtonControl pointerActivated { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.pointerActivateReady"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PointerActivateReady")]
|
||||
public ButtonControl pointerActivateReady { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="HandInteractionProfile.graspValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "GraspValue")]
|
||||
public AxisControl graspValue { get; private set; }
|
||||
/// <summary>
|
||||
/// An [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.graspValue"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "GraspFirm")]
|
||||
public ButtonControl graspFirm { get; private set; }
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="HandInteractionProfile.graspReady"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "GraspReady")]
|
||||
public ButtonControl graspReady { get; private set; }
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping gripPose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 2)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping gripPose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 4)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position. This value is equivalent to mapping gripPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 8, noisy = true, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. This value is equivalent to mapping gripPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 20, noisy = true, alias = "gripRotation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the aim position. This value is equivalent to mapping aimPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 68, noisy = true)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the aim orientation. This value is equivalent to mapping aimPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 80, noisy = true)]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the poke position. This value is equivalent to mapping pokePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 128, noisy = true)]
|
||||
public Vector3Control pokePosition { get; private set; }
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the poke orientation. This value is equivalent to mapping pokePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 140, noisy = true)]
|
||||
public QuaternionControl pokeRotation { get; private set; }
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the pinch position. This value is equivalent to mapping pinchPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 188, noisy = true)]
|
||||
public Vector3Control pinchPosition { get; private set; }
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pinch orientation. This value is equivalent to mapping pinchPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 200, noisy = true)]
|
||||
public QuaternionControl pinchRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
pokePose = GetChildControl<PoseControl>("pokePose");
|
||||
pinchPose = GetChildControl<PoseControl>("pinchPose");
|
||||
pinchValue = GetChildControl<AxisControl>("pinchValue");
|
||||
pinchTouched = GetChildControl<ButtonControl>("pinchTouched");
|
||||
pinchReady = GetChildControl<ButtonControl>("pinchReady");
|
||||
pointerActivateValue = GetChildControl<AxisControl>("pointerActivateValue");
|
||||
pointerActivated = GetChildControl<ButtonControl>("pointerActivated");
|
||||
pointerActivateReady = GetChildControl<ButtonControl>("pointerActivateReady");
|
||||
graspValue = GetChildControl<AxisControl>("graspValue");
|
||||
graspFirm = GetChildControl<ButtonControl>("graspFirm");
|
||||
graspReady = GetChildControl<ButtonControl>("graspReady");
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
pokePosition = GetChildControl<Vector3Control>("pokePosition");
|
||||
pokeRotation = GetChildControl<QuaternionControl>("pokeRotation");
|
||||
pinchPosition = GetChildControl<Vector3Control>("pinchPosition");
|
||||
pinchRotation = GetChildControl<QuaternionControl>("pinchRotation");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference Hand Interaction Profile.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/ext/hand_interaction_ext";
|
||||
|
||||
// Available Bindings
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/poke_ext/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string poke = "/input/poke_ext/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/pinch_ext/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pinch = "/input/pinch_ext/pose";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/pinch_ext/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pinchValue = "/input/pinch_ext/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/pinch_ext/ready_ext' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pinchReady = "/input/pinch_ext/ready_ext";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/aim_activate_ext/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pointerActivateValue = "/input/aim_activate_ext/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/aim_activate_ext/ready_ext' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string pointerActivateReady = "/input/aim_activate_ext/ready_ext";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/grasp_ext/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string graspValue = "/input/grasp_ext/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/grasp_ext/ready_ext' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string graspReady = "/input/grasp_ext/ready_ext";
|
||||
|
||||
private const string kDeviceLocalizedName = "Hand Interaction OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// The OpenXR Extension string. This is used by OpenXR to check if this extension is available or enabled.
|
||||
/// </summary>
|
||||
public const string extensionString = "XR_EXT_hand_interaction";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires hand tracking extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(extensionString))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="HandInteraction"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(HandInteraction),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="HandInteraction"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(HandInteraction));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device in InputSystem.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(HandInteraction);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "handinteraction",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Grip Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Poke Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PokePose",
|
||||
localizedName = "Poke Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Poke"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = poke,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pinch Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PinchPose",
|
||||
localizedName = "Pinch Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pinch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pinch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pinch Value
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PinchValue",
|
||||
localizedName = "Pinch Value",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PinchValue"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pinchValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pinch Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PinchTouched",
|
||||
localizedName = "Pinch Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PinchTouched"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pinchValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pinch Ready
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PinchReady",
|
||||
localizedName = "Pinch Ready",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PinchReady"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pinchReady,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pointer Activate Value
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PointerActivateValue",
|
||||
localizedName = "Pointer Activate Value",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PointerActivateValue"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pointerActivateValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pointer Activated
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PointerActivated",
|
||||
localizedName = "Pointer Activated",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PointerActivated"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pointerActivateValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Pointer Activate Ready
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "PointerActivateReady",
|
||||
localizedName = "Pointer Activate Ready",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PointerActivateReady"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = pointerActivateReady,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grasp Value
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "GraspValue",
|
||||
localizedName = "Grasp Value",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GraspValue"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = graspValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Grasp Firm
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "GraspFirm",
|
||||
localizedName = "Grasp Firm",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GraspFirm"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = graspValue,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Grasp Ready
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "GraspReady",
|
||||
localizedName = "Grasp Ready",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GraspReady"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = graspReady,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5019471fb2174e5c852ecd4047163007
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,324 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of KHR Simple Controllers interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Khronos Simple Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Khronos Simple Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/khrsimplecontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class KHRSimpleControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.khrsimpleprofile";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_khronos_simple_controller_profile">Khronos Simple Controller interaction profile</a>. This device contains one haptic output motor.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Khronos Simple Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class KHRSimpleController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="KHRSimpleControllerProfile.select"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Secondary", "selectbutton" }, usage = "PrimaryButton")]
|
||||
public ButtonControl select { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="KHRSimpleControllerProfile.menu"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menubutton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents information from the <see cref="KHRSimpleControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents information from the <see cref="KHRSimpleControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 2)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set indicating what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 4)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position, or grip position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 8, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation, or grip orientation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 20, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 68)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 80, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="KHRSimpleControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="OpenXRDevice"/>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
select = GetChildControl<ButtonControl>("select");
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OpenXR string that represents the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#semantic-path-interaction-profiles">Interaction Profile.</a>
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/khr/simple_controller";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/select/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string select = "/input/select/click";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../input/output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "KHR Simple Controller OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="KHRSimpleController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(KHRSimpleController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="KHRSimpleController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(typeof(KHRSimpleController).Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(KHRSimpleController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "khrsimplecontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Khronos",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Menu
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "select",
|
||||
localizedName = "Select",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = select,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f6bfdbcb316ed242b30a8798c9eb853
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,902 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Meta Quest Touch Plus controller interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Meta Quest Touch Plus Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Meta Quest Touch Plus Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/metaquesttouchpluscontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "XR_META_touch_controller_plus",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class MetaQuestTouchPlusControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.metaquestplus";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based on the controller interaction profile Meta Touch Controller Plus.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Meta Quest Touch Plus Controller(OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class QuestTouchPlusController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "Joystick" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl thumbstick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.system"/> <see cref="MetaQuestTouchPlusControllerProfile.menu"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menuButton", "systemButton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.buttonA"/> <see cref="MetaQuestTouchPlusControllerProfile.buttonX"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "A", "X", "buttonA", "buttonX" }, usage = "PrimaryButton")]
|
||||
public ButtonControl primaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.buttonATouch"/> <see cref="MetaQuestTouchPlusControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "ATouched", "XTouched", "ATouch", "XTouch", "buttonATouched", "buttonXTouched" }, usage = "PrimaryTouch")]
|
||||
public ButtonControl primaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.buttonB"/> <see cref="MetaQuestTouchPlusControllerProfile.buttonY"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "B", "Y", "buttonB", "buttonY" }, usage = "SecondaryButton")]
|
||||
public ButtonControl secondaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.buttonBTouch"/> <see cref="MetaQuestTouchPlusControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "BTouched", "YTouched", "BTouch", "YTouch", "buttonBTouched", "buttonYTouched" }, usage = "SecondaryTouch")]
|
||||
public ButtonControl secondaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexButton", "indexTouched", "triggerbutton" }, usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.triggerTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexTouch", "indexNearTouched" }, usage = "TriggerTouch")]
|
||||
public ButtonControl triggerTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadPressed", "thumbstickClick", "joystickClicked" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl thumbstickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.thumbstickTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadTouched", "thumbstickTouch", "joystickTouched" }, usage = "Primary2DAxisTouch")]
|
||||
public ButtonControl thumbstickTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.thumbrest"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbrestTouch")]
|
||||
public ButtonControl thumbrestTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MetaQuestTouchPlusControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MetaQuestTouchPlusControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 28, usage = "IsTracked")]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32, usage = "TrackingState")]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position. For the Oculus Touch device, this is both the grip and the pointer position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 36, noisy = true, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. For the Oculus Touch device, this is both the grip and the pointer rotation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 48, noisy = true, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 96)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 108, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="MetaQuestTouchPlusControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.triggerForce"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerForce")]
|
||||
public AxisControl triggerForce { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.triggerCurl"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerCurl")]
|
||||
public AxisControl triggerCurl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.triggerSlide"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerSlide")]
|
||||
public AxisControl triggerSlide { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.triggerProximity"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerProximity")]
|
||||
public ButtonControl triggerProximity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchPlusControllerProfile.thumbProximity"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbProximity")]
|
||||
public ButtonControl thumbProximity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
thumbstick = GetChildControl<StickControl>("thumbstick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
triggerTouched = GetChildControl<ButtonControl>("triggerTouched");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
primaryTouched = GetChildControl<ButtonControl>("primaryTouched");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
secondaryTouched = GetChildControl<ButtonControl>("secondaryTouched");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
thumbrestTouched = GetChildControl<ButtonControl>("thumbrestTouched");
|
||||
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
triggerForce = GetChildControl<AxisControl>("triggerForce");
|
||||
triggerCurl = GetChildControl<AxisControl>("triggerCurl");
|
||||
triggerSlide = GetChildControl<AxisControl>("triggerSlide");
|
||||
triggerProximity = GetChildControl<ButtonControl>("triggerProximity");
|
||||
thumbProximity = GetChildControl<ButtonControl>("thumbProximity");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference Meta Quest Touch Plus Controller.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/meta/touch_controller_plus";
|
||||
|
||||
// Available Bindings
|
||||
// Left Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonX = "/input/x/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonXTouch = "/input/x/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonY = "/input/y/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonYTouch = "/input/y/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
|
||||
// Right Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonA = "/input/a/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonATouch = "/input/a/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '..."/input/b/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonB = "/input/b/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/b/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonBTouch = "/input/b/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string system = "/input/system/click";
|
||||
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/squeeze/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerTouch = "/input/trigger/touch";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '...//input/thumbstick' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickTouch = "/input/thumbstick/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbrest/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbrest = "/input/thumbrest/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/force' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerForce = "/input/trigger/force";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/curl_meta' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerCurl = "/input/trigger/curl_meta";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/slide_meta' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerSlide = "/input/trigger/slide_meta";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/proximity_meta' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerProximity = "/input/trigger/proximity_meta";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumb_meta/proximity_meta' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbProximity = "/input/thumb_meta/proximity_meta";
|
||||
|
||||
private const string kDeviceLocalizedName = "Meta Quest Touch Plus Controller OpenXR";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires the plus controller extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled("XR_META_touch_controller_plus"))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="QuestTouchPlusController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(QuestTouchPlusController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="QuestTouchPlusController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(QuestTouchPlusController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(QuestTouchPlusController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "questtouchpluscontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Oculus",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Joystick
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstick",
|
||||
localizedName = "Thumbstick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Menu
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = system,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryButton",
|
||||
localizedName = "Primary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonX,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonA,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryTouched",
|
||||
localizedName = "Primary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonXTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonATouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryButton",
|
||||
localizedName = "Secondary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonY,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonB,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryTouched",
|
||||
localizedName = "Secondary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonYTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonBTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
// Trigger
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerTouched",
|
||||
localizedName = "Trigger Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Clicked
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickClicked",
|
||||
localizedName = "Thumbstick Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickTouched",
|
||||
localizedName = "Thumbstick Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbrest Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbrestTouched",
|
||||
localizedName = "Thumbrest Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbrestTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbrest,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Force
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerForce",
|
||||
localizedName = "Trigger Force",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerForce"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerForce,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Curl
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerCurl",
|
||||
localizedName = "Trigger Curl",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerCurl"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerCurl,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Slide
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerSlide",
|
||||
localizedName = "Trigger Slide",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerSlide"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerSlide,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Proximity
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerProximity",
|
||||
localizedName = "Trigger Proximity",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerProximity"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerProximity,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumb Proximity
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbProximity",
|
||||
localizedName = "Thumb Proximity",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbProximity"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbProximity,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b7365b139f7aec43b23d26b7a48b5a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,982 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Meta Quest Pro controller interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Meta Quest Touch Pro Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Meta Quest Touch Pro Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/metaquesttouchprocontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "XR_FB_touch_controller_pro",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class MetaQuestTouchProControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.metaquestpro";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based on the controller interaction profile Meta Touch Controller Pro.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Meta Quest Pro Touch Controller(OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class QuestProTouchController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "Joystick" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl thumbstick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.system"/> <see cref="MetaQuestTouchProControllerProfile.menu"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menuButton", "systemButton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.buttonA"/> <see cref="MetaQuestTouchProControllerProfile.buttonX"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "A", "X", "buttonA", "buttonX" }, usage = "PrimaryButton")]
|
||||
public ButtonControl primaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.buttonATouch"/> <see cref="MetaQuestTouchProControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "ATouched", "XTouched", "ATouch", "XTouch", "buttonATouched", "buttonXTouched" }, usage = "PrimaryTouch")]
|
||||
public ButtonControl primaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.buttonB"/> <see cref="MetaQuestTouchProControllerProfile.buttonY"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "B", "Y", "buttonB", "buttonY" }, usage = "SecondaryButton")]
|
||||
public ButtonControl secondaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.buttonBTouch"/> <see cref="MetaQuestTouchProControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "BTouched", "YTouched", "BTouch", "YTouch", "buttonBTouched", "buttonYTouched" }, usage = "SecondaryTouch")]
|
||||
public ButtonControl secondaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexButton", "indexTouched", "triggerbutton" }, usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.triggerTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexTouch", "indexNearTouched" }, usage = "TriggerTouch")]
|
||||
public ButtonControl triggerTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadPressed", "thumbstickClick", "joystickClicked" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl thumbstickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbstickTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadTouched", "thumbstickTouch", "joystickTouched" }, usage = "Primary2DAxisTouch")]
|
||||
public ButtonControl thumbstickTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbrest"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbrestTouch")]
|
||||
public ButtonControl thumbrestTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MetaQuestTouchProControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MetaQuestTouchProControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 28, usage = "IsTracked")]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32, usage = "TrackingState")]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position. For the Oculus Touch device, this is both the grip and the pointer position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 36, noisy = true, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. For the Oculus Touch device, this is both the grip and the pointer rotation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 48, noisy = true, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 96)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 108, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="MetaQuestTouchProControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbrestForce"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbrestForce")]
|
||||
public AxisControl thumbrestForce { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.stylusForce"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "StylusForce")]
|
||||
public AxisControl stylusForce { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.triggerCurl"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerCurl")]
|
||||
public AxisControl triggerCurl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MetaQuestTouchProControllerProfile.triggerSlide"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerSlide")]
|
||||
public AxisControl triggerSlide { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.triggerProximity"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerProximity")]
|
||||
public ButtonControl triggerProximity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MetaQuestTouchProControllerProfile.thumbProximity"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbProximity")]
|
||||
public ButtonControl thumbProximity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="MetaQuestTouchProControllerProfile.hapticTrigger"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "HapticTrigger")]
|
||||
public HapticControl hapticTrigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="MetaQuestTouchProControllerProfile.hapticThumb"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "HapticThumb")]
|
||||
public HapticControl hapticThumb { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
thumbstick = GetChildControl<StickControl>("thumbstick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
triggerTouched = GetChildControl<ButtonControl>("triggerTouched");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
primaryTouched = GetChildControl<ButtonControl>("primaryTouched");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
secondaryTouched = GetChildControl<ButtonControl>("secondaryTouched");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
thumbrestTouched = GetChildControl<ButtonControl>("thumbrestTouched");
|
||||
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
thumbrestForce = GetChildControl<AxisControl>("thumbrestForce");
|
||||
stylusForce = GetChildControl<AxisControl>("stylusForce");
|
||||
triggerCurl = GetChildControl<AxisControl>("triggerCurl");
|
||||
triggerSlide = GetChildControl<AxisControl>("triggerSlide");
|
||||
triggerProximity = GetChildControl<ButtonControl>("triggerProximity");
|
||||
thumbProximity = GetChildControl<ButtonControl>("thumbProximity");
|
||||
hapticTrigger = GetChildControl<HapticControl>("hapticTrigger");
|
||||
hapticThumb = GetChildControl<HapticControl>("hapticThumb");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference Meta Quest Pro Touch Controller.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/facebook/touch_controller_pro";
|
||||
|
||||
// Available Bindings
|
||||
// Left Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonX = "/input/x/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonXTouch = "/input/x/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonY = "/input/y/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonYTouch = "/input/y/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
|
||||
// Right Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonA = "/input/a/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonATouch = "/input/a/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '..."/input/b/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonB = "/input/b/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/b/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonBTouch = "/input/b/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string system = "/input/system/click";
|
||||
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/squeeze/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerTouch = "/input/trigger/touch";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '...//input/thumbstick' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickTouch = "/input/thumbstick/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbrest/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbrest = "/input/thumbrest/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/thumbrest/force' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbrestForce = "/input/thumbrest/force";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/stylus_fb/force' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string stylusForce = "/input/stylus_fb/force";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/curl_fb' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerCurl = "/input/trigger/curl_fb";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/slide_fb' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerSlide = "/input/trigger/slide_fb";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerProximity = "/input/trigger/proximity_fb";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbProximity = "/input/thumb_fb/proximity_fb";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string hapticTrigger = "/output/trigger_haptic_fb";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string hapticThumb = "/output/thumb_haptic_fb";
|
||||
|
||||
private const string kDeviceLocalizedName = "Meta Quest Pro Touch Controller OpenXR";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires the pro controller extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled("XR_FB_touch_controller_pro"))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="QuestProTouchController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(QuestProTouchController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="QuestProTouchController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(QuestProTouchController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(QuestProTouchController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "questprotouchcontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Oculus",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Joystick
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstick",
|
||||
localizedName = "Thumbstick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Menu
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = system,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryButton",
|
||||
localizedName = "Primary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonX,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonA,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryTouched",
|
||||
localizedName = "Primary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonXTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonATouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryButton",
|
||||
localizedName = "Secondary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonY,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonB,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryTouched",
|
||||
localizedName = "Secondary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonYTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonBTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
// Trigger
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerTouched",
|
||||
localizedName = "Trigger Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Clicked
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickClicked",
|
||||
localizedName = "Thumbstick Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickTouched",
|
||||
localizedName = "Thumbstick Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbrest Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbrestTouched",
|
||||
localizedName = "Thumbrest Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbrestTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbrest,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbrestForce",
|
||||
localizedName = "Thumbrest Force",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbrestForce"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbrestForce,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "stylusForce",
|
||||
localizedName = "Stylus Force",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"StylusForce"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = stylusForce,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerCurl",
|
||||
localizedName = "Trigger Curl",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerCurl"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerCurl,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerSlide",
|
||||
localizedName = "Trigger Slide",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerSlide"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerSlide,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Proximity
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerProximity",
|
||||
localizedName = "Trigger Proximity",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerProximity"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerProximity,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumb Proximity
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbProximity",
|
||||
localizedName = "Thumb Proximity",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbProximity"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbProximity,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Haptic Trigger
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "hapticTrigger",
|
||||
localizedName = "Haptic Trigger Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "HapticTrigger" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = hapticTrigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptic Thumb
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "hapticThumb",
|
||||
localizedName = "Haptic Thumb Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "HapticThumb" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = hapticThumb,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4b862ee14fb479fbfe5fffe655d3ed3
|
||||
timeCreated: 1667676951
|
||||
@@ -0,0 +1,353 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Microsoft hand interaction profiles in OpenXR. It enables <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_hand_interaction">XR_MSFT_hand_interaction</a> in the underyling runtime.
|
||||
/// This creates a new <see cref="InputDevice"/> with the <see cref="InputDeviceCharacteristics.HandTracking"/> characteristic.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Microsoft Hand Interaction Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android },
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the hand interaction profile. Will register the controller map for hand interaction if enabled.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/microsofthandinteraction.html",
|
||||
Version = "0.0.1",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class MicrosoftHandInteraction : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.handtracking";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the hand interaction profile in the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_hand_interaction">Hand Interaction Extension</a>. Enabled through <see cref="MicrosoftHandInteraction"/>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Hololens Hand (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class HoloLensHand : XRController
|
||||
{
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MicrosoftHandInteraction.select"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PrimaryAxis")]
|
||||
public AxisControl select { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftHandInteraction.select"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "selectbutton" }, usages = new[] { "PrimaryButton" })]
|
||||
public ButtonControl selectPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// An [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MicrosoftHandInteraction.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "Secondary", usage = "Grip")]
|
||||
public AxisControl squeeze { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftHandInteraction.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usages = new[] { "GripButton" })]
|
||||
public ButtonControl squeezePressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the Microsoft Hand Interaction devicePose OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "device", usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the Microsoft Hand Interaction pointer OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 132)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 136)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position, or grip position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 20, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation, or grip orientation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 80)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 92, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
select = GetChildControl<AxisControl>("select");
|
||||
selectPressed = GetChildControl<ButtonControl>("selectPressed");
|
||||
squeeze = GetChildControl<AxisControl>("squeeze");
|
||||
squeezePressed = GetChildControl<ButtonControl>("squeezePressed");
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The OpenXR Extension string. OpenXR uses this to check if this extension is available or enabled. See <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_hand_interaction">hand interaction extension</a> documentation for more information on this OpenXR extension.</summary>
|
||||
public const string extensionString = "XR_MSFT_hand_interaction";
|
||||
|
||||
/// <summary>
|
||||
/// OpenXR string that represents the hand interaction profile.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/microsoft/hand_interaction";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/select/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string select = "/input/select/value";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/menu/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
|
||||
private const string kDeviceLocalizedName = "HoloLens Hand OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="HoloLensHand"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(HoloLensHand),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="HoloLensHand"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(HoloLensHand));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(HoloLensHand);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "microsofthandinteraction",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Microsoft",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Select
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "select",
|
||||
localizedName = "Select",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = select,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Select Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "selectPressed",
|
||||
localizedName = "Select Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = select,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Squeeze
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "squeeze",
|
||||
localizedName = "Squeeze",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Squeeze Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "squeezePressed",
|
||||
localizedName = "Squeeze Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f928d0d73a35f294fbe357ca17aa3547
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,560 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Microsoft Motion Controllers interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Microsoft Motion Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Microsoft Motion Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/microsoftmotioncontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class MicrosoftMotionControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.microsoftmotioncontroller";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based off the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_microsoft_mixed_reality_motion_controller_profile">Microsoft Mixed Reality Motion Controller</a>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Windows MR Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class WMRSpatialController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="MicrosoftMotionControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "thumbstickaxes", "thumbstick" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl joystick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="MicrosoftMotionControllerProfile.trackpad"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Secondary2DAxis", "touchpadaxes", "trackpad" }, usage = "Secondary2DAxis")]
|
||||
public ThumbstickControl touchpad { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MicrosoftMotionControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.menu"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menubutton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="MicrosoftMotionControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "triggeraxis" }, usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "triggerbutton", usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystickClicked", "thumbstickpressed" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl joystickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.trackpadClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystickorpadpressed", "touchpadpressed", "trackpadClicked" }, usage = "Secondary2DAxisClick")]
|
||||
public ButtonControl touchpadClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="MicrosoftMotionControllerProfile.trackpadTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystickorpadtouched", "touchpadtouched", "trackpadTouched" }, usage = "Secondary2DAxisTouch")]
|
||||
public ButtonControl touchpadTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MicrosoftMotionControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="MicrosoftMotionControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "aimPose" }, usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set indicating what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 36)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position, or grip position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 40, aliases = new[] { "gripPosition" })]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation, or grip orientation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 52, aliases = new[] { "gripOrientation" })]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 100)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 112, aliases = new[] { "pointerOrientation" })]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="MicrosoftMotionControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
joystick = GetChildControl<StickControl>("joystick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
touchpad = GetChildControl<StickControl>("touchpad");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
joystickClicked = GetChildControl<ButtonControl>("joystickClicked");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
touchpadClicked = GetChildControl<ButtonControl>("touchpadClicked");
|
||||
touchpadTouched = GetChildControl<ButtonControl>("touchPadTouched");
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_microsoft_mixed_reality_motion_controller_profile">Microsoft Mixed Reality Motion Controller</a>.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/microsoft/motion_controller";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/squeeze/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/click";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/thumbstick' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/trackpad' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpad = "/input/trackpad";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trackpad/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpadClick = "/input/trackpad/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trackpad/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trackpadTouch = "/input/trackpad/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "Windows MR Controller OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="WMRSpatialController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(WMRSpatialController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="WMRSpatialController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(WMRSpatialController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(WMRSpatialController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "microsoftmotioncontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Microsoft",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Joystick
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "joystick",
|
||||
localizedName = "Joystick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Touchpad
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "touchpad",
|
||||
localizedName = "Touchpad",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpad,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Menu
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Joystick Clicked
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "joystickClicked",
|
||||
localizedName = "JoystickClicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Touchpad Clicked
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "touchpadClicked",
|
||||
localizedName = "Touchpad Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Touchpad Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "touchpadTouched",
|
||||
localizedName = "Touchpad Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 761fdd4502cb7a84e9ec7a2b24f33f37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,741 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Oculus TouchControllers interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Oculus Touch Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Oculus Touch Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/oculustouchcontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class OculusTouchControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.oculustouch";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based on the hand interaction profile in the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_oculus_touch_controller_profile">Oculus Touch Controller</a>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Oculus Touch Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class OculusTouchController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="OculusTouchControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "Joystick" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl thumbstick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="OculusTouchControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.system"/> <see cref="OculusTouchControllerProfile.menu"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "Primary", "menuButton", "systemButton" }, usage = "MenuButton")]
|
||||
public ButtonControl menu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.buttonA"/> <see cref="OculusTouchControllerProfile.buttonX"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "A", "X", "buttonA", "buttonX" }, usage = "PrimaryButton")]
|
||||
public ButtonControl primaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.buttonATouch"/> <see cref="OculusTouchControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "ATouched", "XTouched", "ATouch", "XTouch", "buttonATouched", "buttonXTouched" }, usage = "PrimaryTouch")]
|
||||
public ButtonControl primaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.buttonB"/> <see cref="OculusTouchControllerProfile.buttonY"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "B", "Y", "buttonB", "buttonY" }, usage = "SecondaryButton")]
|
||||
public ButtonControl secondaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.buttonBTouch"/> <see cref="OculusTouchControllerProfile.buttonYTouch"/> OpenXR bindings, depending on handedness.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "BTouched", "YTouched", "BTouch", "YTouch", "buttonBTouched", "buttonYTouched" }, usage = "SecondaryTouch")]
|
||||
public ButtonControl secondaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="OculusTouchControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexButton", "indexTouched", "triggerbutton" }, usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.triggerTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "indexTouch", "indexNearTouched" }, usage = "TriggerTouch")]
|
||||
public ButtonControl triggerTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadPressed", "thumbstickClick", "joystickClicked" }, usage = "Primary2DAxisClick")]
|
||||
public ButtonControl thumbstickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.thumbstickTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "JoystickOrPadTouched", "thumbstickTouch", "joystickTouched" }, usage = "Primary2DAxisTouch")]
|
||||
public ButtonControl thumbstickTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="OculusTouchControllerProfile.thumbrest"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "ThumbrestTouch")]
|
||||
public ButtonControl thumbrestTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="OculusTouchControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="OculusTouchControllerProfile.aim"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 28, usage = "IsTracked")]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 32, usage = "TrackingState")]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position. For the Oculus Touch device, this is both the grip and the pointer position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 36, noisy = true, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. For the Oculus Touch device, this is both the grip and the pointer rotation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 48, noisy = true, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for back compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 96)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 108, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="OculusTouchControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
thumbstick = GetChildControl<StickControl>("thumbstick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
triggerTouched = GetChildControl<ButtonControl>("triggerTouched");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
primaryTouched = GetChildControl<ButtonControl>("primaryTouched");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
secondaryTouched = GetChildControl<ButtonControl>("secondaryTouched");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
thumbrestTouched = GetChildControl<ButtonControl>("thumbrestTouched");
|
||||
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_oculus_touch_controller_profile">Oculus Touch Controller</a>.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/oculus/touch_controller";
|
||||
|
||||
// Available Bindings
|
||||
// Left Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonX = "/input/x/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/x/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonXTouch = "/input/x/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonY = "/input/y/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/y/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonYTouch = "/input/y/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/menu/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.leftHand"/> user path.
|
||||
/// </summary>
|
||||
public const string menu = "/input/menu/click";
|
||||
|
||||
// Right Hand Only
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonA = "/input/a/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonATouch = "/input/a/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '..."/input/b/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonB = "/input/b/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/b/touch' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string buttonBTouch = "/input/b/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/click' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs. This binding is only available for the <see cref="OpenXRInteractionFeature.UserPaths.rightHand"/> user path.
|
||||
/// </summary>
|
||||
public const string system = "/input/system/click";
|
||||
|
||||
// Both Hands
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string triggerTouch = "/input/trigger/touch";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbstickTouch = "/input/thumbstick/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string thumbrest = "/input/thumbrest/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by input subsystem to bind actions to physical inputs.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "Oculus Touch Controller OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="OculusTouchController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(OculusTouchController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="OculusTouchController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(OculusTouchController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(OculusTouchController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "oculustouchcontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Oculus",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
// Joystick
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstick",
|
||||
localizedName = "Thumbstick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Grip Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Menu
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "menu",
|
||||
localizedName = "Menu",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = menu,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = system,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryButton",
|
||||
localizedName = "Primary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonX,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonA,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//A / X Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryTouched",
|
||||
localizedName = "Primary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonXTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonATouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Press
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryButton",
|
||||
localizedName = "Secondary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonY,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonB,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
//B / Y Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryTouched",
|
||||
localizedName = "Secondary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonYTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.leftHand }
|
||||
},
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonBTouch,
|
||||
interactionProfileName = profile,
|
||||
userPaths = new List<string>() { UserPaths.rightHand }
|
||||
},
|
||||
}
|
||||
},
|
||||
// Trigger
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Trigger Pressed
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Trigger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Trigger Touch
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerTouched",
|
||||
localizedName = "Trigger Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Clicked
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickClicked",
|
||||
localizedName = "Thumbstick Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbstick Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickTouched",
|
||||
localizedName = "Thumbstick Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
//Thumbrest Touched
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbrestTouched",
|
||||
localizedName = "Thumbrest Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"ThumbrestTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbrest,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: feeef8d85de8db242bdda70cc7ff5acd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Palm Pose feature in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Palm Pose",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android},
|
||||
Company = "Unity",
|
||||
Desc = "Add Palm pose feature and if enabled, extra palm pose path /input/palm_ext/pose will be added to regular interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/palmposeinteraction.html",
|
||||
OpenxrExtensionStrings = extensionString,
|
||||
Version = "0.0.1",
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class PalmPoseInteraction : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.palmpose";
|
||||
|
||||
/// <summary>
|
||||
/// A flag to mark this Palm Pose feature is additive.
|
||||
/// </summary>
|
||||
internal override bool IsAdditive => true;
|
||||
|
||||
/// <summary>
|
||||
/// Palm Pose interaction feature supports an input patch for the palm pose.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Palm Pose (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class PalmPose : XRController
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="PalmPoseInteraction.palmPose"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0)]
|
||||
public PoseControl palmPose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping palmPose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set to indicate what data is valid. This value is equivalent to mapping palmPose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 4)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position. This value is equivalent to mapping palmPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 8, noisy = true, alias = "palmPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation. This value is equivalent to mapping palmPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 20, noisy = true, alias = "palmRotation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the palm pose position. This value is equivalent to mapping palmPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 8, noisy = true)]
|
||||
public Vector3Control palmPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the palm pose orientation. This value is equivalent to mapping palmPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 20, noisy = true)]
|
||||
public QuaternionControl palmRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal call used to assign controls to the the correct element.
|
||||
/// </summary>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
palmPose = GetChildControl<PoseControl>("palmPose");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../palm_ext/pose' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string palmPose = "/input/palm_ext/pose";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../grip_surface/pose' OpenXR Input Binding, which is supported in OpenXR 1.1 specification
|
||||
/// </summary>
|
||||
public const string gripSurfacePose = "/input/grip_surface/pose";
|
||||
|
||||
/// <summary>
|
||||
/// A unique string for palm pose feature
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/ext/palmpose";
|
||||
|
||||
private const string kDeviceLocalizedName = "Palm Pose Interaction OpenXR";
|
||||
/// <summary>
|
||||
/// The OpenXR Extension string. This is used by OpenXR to check if this extension is available or enabled.
|
||||
/// </summary>
|
||||
public const string extensionString = "XR_EXT_palm_pose";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected internal override void GetValidationChecks(List<OpenXRFeature.ValidationRule> results, BuildTargetGroup target)
|
||||
{
|
||||
results.Add( new ValidationRule(this){
|
||||
message = "Additive Interaction feature requires a valid controller or hand interaction profile selected within Interaction Profiles.",
|
||||
error = true,
|
||||
errorEnteringPlaymode = true,
|
||||
checkPredicate = () =>
|
||||
{
|
||||
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(target);
|
||||
if (null == settings)
|
||||
return false;
|
||||
|
||||
bool palmPoseFeatureEnabled = false;
|
||||
bool otherNonAdditiveInteractionFeatureEnabled = false;
|
||||
foreach (var feature in settings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
if (feature.enabled)
|
||||
{
|
||||
if (feature is PalmPoseInteraction)
|
||||
palmPoseFeatureEnabled = true;
|
||||
else if (!(feature as OpenXRInteractionFeature).IsAdditive && !(feature is EyeGazeInteraction))
|
||||
otherNonAdditiveInteractionFeatureEnabled = true;
|
||||
}
|
||||
}
|
||||
return palmPoseFeatureEnabled && otherNonAdditiveInteractionFeatureEnabled;
|
||||
},
|
||||
fixIt = () => SettingsService.OpenProjectSettings("Project/XR Plug-in Management/OpenXR"),
|
||||
fixItAutomatic = false,
|
||||
fixItMessage = "Open Project Settings to select one or more non Additive interaction profiles."
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong instance)
|
||||
{
|
||||
// Requires the palmPose extension
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(extensionString))
|
||||
return false;
|
||||
|
||||
return base.OnInstanceCreate(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="PalmPose"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(PalmPose),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="PalmPose"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(PalmPose));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(PalmPose);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "palmposeinteraction",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "palmpose",
|
||||
localizedName = "Palm Pose",
|
||||
type = ActionType.Pose,
|
||||
bindings = AddBindingBasedOnRuntimeAPIVersion(),
|
||||
isAdditive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine path binding based on current runtime API version.
|
||||
/// </summary>
|
||||
internal List<ActionBinding> AddBindingBasedOnRuntimeAPIVersion()
|
||||
{
|
||||
List<ActionBinding> pairingActionBinding;
|
||||
if (OpenXRRuntime.isRuntimeAPIVersionGreaterThan1_1())
|
||||
{
|
||||
pairingActionBinding = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = gripSurfacePose,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
pairingActionBinding = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = palmPose,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return pairingActionBinding;
|
||||
}
|
||||
/// <summary>
|
||||
/// Process additive actions: add additional supported additive actions to existing controller profiles
|
||||
/// </summary>
|
||||
internal override void AddAdditiveActions(List<OpenXRInteractionFeature.ActionMapConfig> actionMaps, ActionMapConfig additiveMap)
|
||||
{
|
||||
foreach (var actionMap in actionMaps)
|
||||
{
|
||||
//valid userPath is user/hand/left or user/hand/right
|
||||
var validUserPath = actionMap.deviceInfos.Where(d => d.userPath != null && ((String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.leftHand) == 0) ||
|
||||
(String.CompareOrdinal(d.userPath, OpenXRInteractionFeature.UserPaths.rightHand) == 0)));
|
||||
if (!validUserPath.Any())
|
||||
continue;
|
||||
|
||||
foreach (var additiveAction in additiveMap.actions.Where(a => a.isAdditive))
|
||||
{
|
||||
actionMap.actions.Add(additiveAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f028123e2efe1d443875bc7609b4a98b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,785 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
#if USE_INPUT_SYSTEM_POSE_CONTROL
|
||||
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
|
||||
#else
|
||||
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
|
||||
#endif
|
||||
|
||||
#if USE_STICK_CONTROL_THUMBSTICKS
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.StickControl; // If replaced, make sure the control extends Vector2Control
|
||||
#else
|
||||
using ThumbstickControl = UnityEngine.InputSystem.Controls.Vector2Control;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// This <see cref="OpenXRInteractionFeature"/> enables the use of Valve Index Controllers interaction profiles in OpenXR.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Valve Index Controller Profile",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA },
|
||||
Company = "Unity",
|
||||
Desc = "Allows for mapping input to the Valve Index Controller interaction profile.",
|
||||
DocumentationLink = Constants.k_DocumentationManualURL + "features/valveindexcontrollerprofile.html",
|
||||
OpenxrExtensionStrings = "",
|
||||
Version = "0.0.1",
|
||||
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class ValveIndexControllerProfile : OpenXRInteractionFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "com.unity.openxr.feature.input.valveindex";
|
||||
|
||||
/// <summary>
|
||||
/// An Input System device based on the hand interaction profile in the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_valve_index_controller_profile">Valve Index Controller</a>.
|
||||
/// </summary>
|
||||
[Preserve, InputControlLayout(displayName = "Index Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
|
||||
public class ValveIndexController : XRControllerWithRumble
|
||||
{
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.system"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "systemButton", usage = "MenuButton")]
|
||||
public ButtonControl system { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.systemTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "MenuTouch")]
|
||||
public ButtonControl systemTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.buttonA"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PrimaryButton")]
|
||||
public ButtonControl primaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.buttonATouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "PrimaryTouch")]
|
||||
public ButtonControl primaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.buttonB"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "SecondaryButton")]
|
||||
public ButtonControl secondaryButton { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.buttonBTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "SecondaryTouch")]
|
||||
public ButtonControl secondaryTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="ValveIndexControllerProfile.squeeze"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripAxis", "squeeze" }, usage = "Grip")]
|
||||
public AxisControl grip { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the Valve Index Controller Profile gripPressed OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "GripButton", "squeezeClicked" }, usage = "GripButton")]
|
||||
public ButtonControl gripPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="ValveIndexControllerProfile.squeezeForce"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "squeezeForce", usage = "GripForce")]
|
||||
public AxisControl gripForce { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="ValveIndexControllerProfile.trigger"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Trigger")]
|
||||
public AxisControl trigger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.triggerClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerButton")]
|
||||
public ButtonControl triggerPressed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.triggerTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "TriggerTouch")]
|
||||
public ButtonControl triggerTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="ValveIndexControllerProfile.thumbstick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "joystick", "Primary2DAxis" }, usage = "Primary2DAxis")]
|
||||
public ThumbstickControl thumbstick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.thumbstickClick"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "joystickClicked", usage = "Primary2DAxisClick")]
|
||||
public ButtonControl thumbstickClicked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.thumbstickTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "joystickTouched", usage = "Primary2DAxisTouch")]
|
||||
public ButtonControl thumbstickTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector2Control](xref:UnityEngine.InputSystem.Controls.Vector2Control)/[StickControl](xref:UnityEngine.InputSystem.Controls.StickControl) that represents the <see cref="ValveIndexControllerProfile.trackpad"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(aliases = new[] { "touchpad", "Secondary2DAxis" }, usage = "Secondary2DAxis")]
|
||||
public ThumbstickControl trackpad { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) that represents the <see cref="ValveIndexControllerProfile.trackpadTouch"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "touchpadTouched", usage = "Secondary2DAxisTouch")]
|
||||
public ButtonControl trackpadTouched { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [AxisControl](xref:UnityEngine.InputSystem.Controls.AxisControl) that represents the <see cref="ValveIndexControllerProfile.trackpadForce"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(alias = "touchpadForce", usage = "Secondary2DAxisForce")]
|
||||
public AxisControl trackpadForce { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the <see cref="ValveIndexControllerProfile.grip"/> OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, aliases = new[] { "device", "gripPose" }, usage = "Device")]
|
||||
public PoseControl devicePose { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PoseControl"/> that represents the Valve Index Controller Profile pointer OpenXR binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 0, alias = "aimPose", usage = "Pointer")]
|
||||
public PoseControl pointer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [ButtonControl](xref:UnityEngine.InputSystem.Controls.ButtonControl) required for backwards compatibility with the XRSDK layouts. This represents the overall tracking state of the device. This value is equivalent to mapping devicePose/isTracked.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 53)]
|
||||
new public ButtonControl isTracked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [IntegerControl](xref:UnityEngine.InputSystem.Controls.IntegerControl) required for backwards compatibility with the XRSDK layouts. This represents the bit flag set indicating what data is valid. This value is equivalent to mapping devicePose/trackingState.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 56)]
|
||||
new public IntegerControl trackingState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the device position, or grip position. This value is equivalent to mapping devicePose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 60, alias = "gripPosition")]
|
||||
new public Vector3Control devicePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the device orientation, or grip orientation. This value is equivalent to mapping devicePose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 72, alias = "gripOrientation")]
|
||||
new public QuaternionControl deviceRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [Vector3Control](xref:UnityEngine.InputSystem.Controls.Vector3Control) required for backwards compatibility with the XRSDK layouts. This is the pointer position. This value is equivalent to mapping pointerPose/position.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 120)]
|
||||
public Vector3Control pointerPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A [QuaternionControl](xref:UnityEngine.InputSystem.Controls.QuaternionControl) required for backwards compatibility with the XRSDK layouts. This is the pointer rotation. This value is equivalent to mapping pointerPose/rotation.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(offset = 132, alias = "pointerOrientation")]
|
||||
public QuaternionControl pointerRotation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="HapticControl"/> that represents the <see cref="ValveIndexControllerProfile.haptic"/> binding.
|
||||
/// </summary>
|
||||
[Preserve, InputControl(usage = "Haptic")]
|
||||
public HapticControl haptic { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="OpenXRDevice"/>
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
system = GetChildControl<ButtonControl>("system");
|
||||
systemTouched = GetChildControl<ButtonControl>("systemTouched");
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
primaryTouched = GetChildControl<ButtonControl>("primaryTouched");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
secondaryTouched = GetChildControl<ButtonControl>("secondaryTouched");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
gripForce = GetChildControl<AxisControl>("gripForce");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
triggerTouched = GetChildControl<ButtonControl>("triggerTouched");
|
||||
thumbstick = GetChildControl<StickControl>("thumbstick");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
trackpad = GetChildControl<StickControl>("trackpad");
|
||||
trackpadTouched = GetChildControl<ButtonControl>("trackpadTouched");
|
||||
trackpadForce = GetChildControl<AxisControl>("trackpadForce");
|
||||
devicePose = GetChildControl<PoseControl>("devicePose");
|
||||
pointer = GetChildControl<PoseControl>("pointer");
|
||||
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
devicePosition = GetChildControl<Vector3Control>("devicePosition");
|
||||
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
|
||||
haptic = GetChildControl<HapticControl>("haptic");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The interaction profile string used to reference the <a href="https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_valve_index_controller_profile">Valve Index Controller</a>.
|
||||
/// </summary>
|
||||
public const string profile = "/interaction_profiles/valve/index_controller";
|
||||
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/click' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string system = "/input/system/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/system/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string systemTouch = "/input/system/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/click' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string buttonA = "/input/a/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/a/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string buttonATouch = "/input/a/touch";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/b/click' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string buttonB = "/input/b/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/b/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string buttonBTouch = "/input/b/touch";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/squeeze/value' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string squeeze = "/input/squeeze/value";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/squeeze/force' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string squeezeForce = "/input/squeeze/force";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/click' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string triggerClick = "/input/trigger/click";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trigger/value' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trigger = "/input/trigger/value";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trigger/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string triggerTouch = "/input/trigger/touch";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/thumbstick' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstick = "/input/thumbstick";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/click' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickClick = "/input/thumbstick/click";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/thumbstick/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string thumbstickTouch = "/input/thumbstick/touch";
|
||||
/// <summary>
|
||||
/// Constant for a Vector2 interaction binding '.../input/trackpad' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpad = "/input/trackpad";
|
||||
/// <summary>
|
||||
/// Constant for a float interaction binding '.../input/trackpad/force' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadForce = "/input/trackpad/force";
|
||||
/// <summary>
|
||||
/// Constant for a boolean interaction binding '.../input/trackpad/touch' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string trackpadTouch = "/input/trackpad/touch";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/grip/pose' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string grip = "/input/grip/pose";
|
||||
/// <summary>
|
||||
/// Constant for a pose interaction binding '.../input/aim/pose' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string aim = "/input/aim/pose";
|
||||
/// <summary>
|
||||
/// Constant for a haptic interaction binding '.../output/haptic' OpenXR Input Binding.
|
||||
/// </summary>
|
||||
public const string haptic = "/output/haptic";
|
||||
|
||||
private const string kDeviceLocalizedName = "Index Controller OpenXR";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="ValveIndexController"/> layout with the Input System.
|
||||
/// </summary>
|
||||
protected override void RegisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RegisterLayout(typeof(ValveIndexController),
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(kDeviceLocalizedName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="ValveIndexController"/> layout from the Input System.
|
||||
/// </summary>
|
||||
protected override void UnregisterDeviceLayout()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return;
|
||||
#endif
|
||||
InputSystem.InputSystem.RemoveLayout(nameof(ValveIndexController));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout string that used for registering device for the Input System.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected override string GetDeviceLayoutName()
|
||||
{
|
||||
return nameof(ValveIndexController);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
ActionMapConfig actionMap = new ActionMapConfig()
|
||||
{
|
||||
name = "valveindexcontroller",
|
||||
localizedName = kDeviceLocalizedName,
|
||||
desiredInteractionProfile = profile,
|
||||
manufacturer = "Valve",
|
||||
serialNumber = "",
|
||||
deviceInfos = new List<DeviceConfig>()
|
||||
{
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
|
||||
userPath = UserPaths.leftHand
|
||||
},
|
||||
new DeviceConfig()
|
||||
{
|
||||
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
|
||||
userPath = UserPaths.rightHand
|
||||
}
|
||||
},
|
||||
actions = new List<ActionConfig>()
|
||||
{
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "system",
|
||||
localizedName = "System",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = system,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "systemTouched",
|
||||
localizedName = "System Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"MenuTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = systemTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryButton",
|
||||
localizedName = "Primary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonA,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "primaryTouched",
|
||||
localizedName = "Primary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"PrimaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonATouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryButton",
|
||||
localizedName = "Secondary Button",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonB,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "secondaryTouched",
|
||||
localizedName = "Secondary Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"SecondaryTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = buttonBTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "grip",
|
||||
localizedName = "Grip",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Grip"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripPressed",
|
||||
localizedName = "Grip Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeeze,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "gripForce",
|
||||
localizedName = "Grip Force",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"GripForce"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = squeezeForce,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trigger",
|
||||
localizedName = "Trigger",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Trigger"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trigger,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerPressed",
|
||||
localizedName = "Triggger Pressed",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerButton"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "triggerTouched",
|
||||
localizedName = "Trigger Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"TriggerTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = triggerTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstick",
|
||||
localizedName = "Thumbstick",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickClicked",
|
||||
localizedName = "Thumbstick Clicked",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisClick"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickClick,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "thumbstickTouched",
|
||||
localizedName = "Thumbstick Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Primary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = thumbstickTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpad",
|
||||
localizedName = "Trackpad",
|
||||
type = ActionType.Axis2D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxis"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpad,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadForce",
|
||||
localizedName = "Trackpad Force",
|
||||
type = ActionType.Axis1D,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxisForce"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadForce,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "trackpadTouched",
|
||||
localizedName = "Trackpad Touched",
|
||||
type = ActionType.Binary,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Secondary2DAxisTouch"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = trackpadTouch,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Device Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "devicePose",
|
||||
localizedName = "Device Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Device"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = grip,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Pointer Pose
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "pointer",
|
||||
localizedName = "Pointer Pose",
|
||||
type = ActionType.Pose,
|
||||
usages = new List<string>()
|
||||
{
|
||||
"Pointer"
|
||||
},
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = aim,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Haptics
|
||||
new ActionConfig()
|
||||
{
|
||||
name = "haptic",
|
||||
localizedName = "Haptic Output",
|
||||
type = ActionType.Vibrate,
|
||||
usages = new List<string>() { "Haptic" },
|
||||
bindings = new List<ActionBinding>()
|
||||
{
|
||||
new ActionBinding()
|
||||
{
|
||||
interactionPath = haptic,
|
||||
interactionProfileName = profile,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddActionMap(actionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d6ccd3d0ef0f1d458e69421dccbdae1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
823
Packages/com.unity.xr.openxr/Runtime/Features/OpenXRFeature.cs
Normal file
823
Packages/com.unity.xr.openxr/Runtime/Features/OpenXRFeature.cs
Normal file
@@ -0,0 +1,823 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
using UnityEngine.XR.OpenXR.Input;
|
||||
using UnityEngine.XR.OpenXR.NativeTypes;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.OpenXR;
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.XR.OpenXR.Editor")]
|
||||
[assembly: InternalsVisibleTo("UnityEditor.XR.OpenXR.Tests")]
|
||||
namespace UnityEngine.XR.OpenXR.Features
|
||||
{
|
||||
/// <summary>
|
||||
/// A Unity OpenXR Feature.
|
||||
/// This class can be inherited from to add feature specific data and logic.
|
||||
/// Feature-specific settings are serialized for access at runtime.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract partial class OpenXRFeature : ScriptableObject
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
internal static Func<string, bool> canSetFeatureDisabled;
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Feature will be enabled when OpenXR is initialized.
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("enabled")] [HideInInspector] [SerializeField] private bool m_enabled = false;
|
||||
|
||||
internal bool failedInitialization { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// True if a required feature failed initialization, false if all features initialized successfully.
|
||||
/// </summary>
|
||||
internal static bool requiredFeatureFailed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Feature is enabled and will be started when the OpenXR loader is initialized.
|
||||
///
|
||||
/// Note that the enabled state of a feature cannot be modified once OpenXR is initialized and
|
||||
/// can be used at runtime to determine if a feature successfully initialized.
|
||||
/// </summary>
|
||||
public bool enabled
|
||||
{
|
||||
get => m_enabled && (OpenXRLoaderBase.Instance == null || !failedInitialization);
|
||||
set
|
||||
{
|
||||
if (enabled == value)
|
||||
return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (canSetFeatureDisabled != null && !value && !canSetFeatureDisabled.Invoke(featureIdInternal))
|
||||
return;
|
||||
#endif //UNITY_EDITOR
|
||||
|
||||
if (OpenXRLoaderBase.Instance != null)
|
||||
{
|
||||
Debug.LogError("OpenXRFeature.enabled cannot be changed while OpenXR is running");
|
||||
return;
|
||||
}
|
||||
|
||||
m_enabled = value;
|
||||
|
||||
OnEnabledChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// Name of the feature.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal string nameUi = null;
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// Version of the feature.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal string version = null;
|
||||
|
||||
/// <summary>
|
||||
/// Feature id.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal string featureIdInternal = null;
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// OpenXR runtime extension strings that need to be enabled to use this extension.
|
||||
/// May contain multiple extensions separated by spaces.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal string openxrExtensionStrings = null;
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// Company name of the author of the feature.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal string company = null;
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// Priority of the feature.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal int priority = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Automatically filled out by the build process from OpenXRFeatureAttribute.
|
||||
/// True if the feature is required, false otherwise.
|
||||
/// </summary>
|
||||
[HideInInspector] [SerializeField] internal bool required = false;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the internal fields have been updated in the current domain
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
internal bool internalFieldsUpdated = false;
|
||||
|
||||
/// <summary>
|
||||
/// Accessor for xrGetInstanceProcAddr function pointer.
|
||||
/// </summary>
|
||||
protected static IntPtr xrGetInstanceProcAddr => Internal_GetProcAddressPtr(false);
|
||||
|
||||
/// <summary>
|
||||
/// Called to hook xrGetInstanceProcAddr.
|
||||
/// Returning a different function pointer allows intercepting any OpenXR method.
|
||||
/// </summary>
|
||||
/// <param name="func">xrGetInstanceProcAddr native function pointer</param>
|
||||
/// <returns>Function pointer that Unity will use to look up OpenXR native functions.</returns>
|
||||
protected internal virtual IntPtr HookGetInstanceProcAddr(IntPtr func) => func;
|
||||
|
||||
/// <summary>
|
||||
/// Called after the OpenXR Loader is initialized and has created its subsystems.
|
||||
/// </summary>
|
||||
protected internal virtual void OnSubsystemCreate() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called after the OpenXR loader has started its subsystems.
|
||||
/// </summary>
|
||||
protected internal virtual void OnSubsystemStart() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called before the OpenXR loader stops its subsystems.
|
||||
/// </summary>
|
||||
protected internal virtual void OnSubsystemStop() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called before the OpenXR loader destroys its subsystems.
|
||||
/// </summary>
|
||||
protected internal virtual void OnSubsystemDestroy() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called after `xrCreateInstance`. Override this method to validate that any necessary OpenXR extensions were
|
||||
/// successfully enabled (<see cref="OpenXRRuntime.IsExtensionEnabled">OpenXRRuntime.IsExtensionEnabled</see>)
|
||||
/// and that any required system properties are supported. If this method returns <see langword="false"/>,
|
||||
/// the feature's <see cref="OpenXRFeature.enabled"/> property is set to <see langword="false"/>.
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">Handle of the native `xrInstance`.</param>
|
||||
/// <returns><see langword="true"/> if this feature successfully initialized. Otherwise, <see langword="false"/>.</returns>
|
||||
/// <remarks>
|
||||
/// If this feature is a required feature of an enabled feature set, returning <see langword="false"/> here
|
||||
/// causes the `OpenXRLoader` to fail, and XR Plug-in Management will fall back to another loader if enabled.
|
||||
/// </remarks>
|
||||
/// <seealso href="xref:openxr-features#enabling-openxr-spec-extension-strings">Enabling OpenXR spec extension strings</seealso>
|
||||
protected internal virtual bool OnInstanceCreate(ulong xrInstance) => true;
|
||||
|
||||
/// <summary>
|
||||
/// Called after xrGetSystem.
|
||||
/// </summary>
|
||||
/// <param name="xrSystem">Handle of the xrSystemId</param>
|
||||
protected internal virtual void OnSystemChange(ulong xrSystem) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called after xrCreateSession.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">Handle of the xrSession</param>
|
||||
protected internal virtual void OnSessionCreate(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the reference xrSpace for the app changes.
|
||||
/// </summary>
|
||||
/// <param name="xrSpace">Handle of the xrSpace</param>
|
||||
protected internal virtual void OnAppSpaceChange(ulong xrSpace) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the OpenXR loader receives the XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED event
|
||||
/// from the runtime signaling that the XrSessionState has changed.
|
||||
/// </summary>
|
||||
/// <param name="oldState">Previous state</param>
|
||||
/// <param name="newState">New state</param>
|
||||
protected internal virtual void OnSessionStateChange(int oldState, int newState) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called after xrSessionBegin.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">Handle of the xrSession</param>
|
||||
protected internal virtual void OnSessionBegin(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called before xrEndSession.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">Handle of the xrSession</param>
|
||||
protected internal virtual void OnSessionEnd(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the runtime transitions to the XR_SESSION_STATE_EXITING state.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">Handle of the xrSession</param>
|
||||
protected internal virtual void OnSessionExiting(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called before xrDestroySession.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">Handle of the xrSession</param>
|
||||
protected internal virtual void OnSessionDestroy(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called before xrDestroyInstance
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">Handle of the xrInstance</param>
|
||||
protected internal virtual void OnInstanceDestroy(ulong xrInstance) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the runtime transitions to the XR_SESSION_STATE_LOSS_PENDING
|
||||
/// state. This is a notification to the feature implementer that the session is
|
||||
/// about to be lost. This feature should do what it needs to do to
|
||||
/// prepare for potential session recreation.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">The session that is going to be lost</param>
|
||||
protected internal virtual void OnSessionLossPending(ulong xrSession) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the OpenXR loader receives the XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING event
|
||||
/// from the runtime. This is a notification to the feature implementer that the instance is
|
||||
/// about to be lost. This feature should do what it needs to do to
|
||||
/// clean up in preparation for termination.
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">The instance that is going to be lost</param>
|
||||
protected internal virtual void OnInstanceLossPending(ulong xrInstance) { }
|
||||
|
||||
/// <summary>
|
||||
/// Notification to the feature implementer that the form factor has changed.
|
||||
/// </summary>
|
||||
/// <param name="xrFormFactor">New form factor value</param>
|
||||
protected internal virtual void OnFormFactorChange(int xrFormFactor) { }
|
||||
|
||||
/// <summary>
|
||||
/// Notification to the feature implementer that the view configuration type has changed.
|
||||
/// </summary>
|
||||
/// <param name="xrViewConfigurationType">New view configuration type</param>
|
||||
protected internal virtual void OnViewConfigurationTypeChange(int xrViewConfigurationType) { }
|
||||
|
||||
/// <summary>
|
||||
/// Notification to the feature implementer that the environment blend mode has changed.
|
||||
/// </summary>
|
||||
/// <param name="xrEnvironmentBlendMode">New environment blend mode value</param>
|
||||
protected internal virtual void OnEnvironmentBlendModeChange(XrEnvironmentBlendMode xrEnvironmentBlendMode) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the enabled state of a feature changes
|
||||
/// </summary>
|
||||
protected internal virtual void OnEnabledChange()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an XrPath to a string.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to convert</param>
|
||||
/// <returns>String that represents the path, or null if the path is invalid.</returns>
|
||||
protected static string PathToString(ulong path) =>
|
||||
Internal_PathToStringPtr(path, out var stringPtr) ? Marshal.PtrToStringAnsi(stringPtr) : null;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to an XrPath.
|
||||
/// </summary>
|
||||
/// <param name="str">String to convert</param>
|
||||
/// <returns>Path of converted string, or XrPath.none if string could not be converted.</returns>
|
||||
protected static ulong StringToPath(string str) =>
|
||||
Internal_StringToPath(str, out var id) ? id : 0ul;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path of the current interaction profile for the given user path.
|
||||
/// </summary>
|
||||
/// <param name="userPath">OpenXR User Path (eg: /user/hand/left)</param>
|
||||
/// <returns>A path to the interaction profile, or XrPath.none if the path could not be retrieved.</returns>
|
||||
protected static ulong GetCurrentInteractionProfile(ulong userPath) =>
|
||||
Internal_GetCurrentInteractionProfile(userPath, out ulong profileId) ? profileId : 0ul;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path of the current interaction profile for the given user path.
|
||||
/// </summary>
|
||||
/// <param name="userPath">User path</param>
|
||||
/// <returns>A path to the interaction profile, or XrPath.none if the path could not be retrieved.</returns>
|
||||
protected static ulong GetCurrentInteractionProfile(string userPath) =>
|
||||
GetCurrentInteractionProfile(StringToPath(userPath));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current app space.
|
||||
/// </summary>
|
||||
/// <returns>Current app space</returns>
|
||||
protected static ulong GetCurrentAppSpace() =>
|
||||
Internal_GetAppSpace(out ulong appSpaceId) ? appSpaceId : 0ul;
|
||||
|
||||
/// <summary>
|
||||
/// Returns viewConfigurationType for the given renderPass index.
|
||||
/// </summary>
|
||||
/// <param name="renderPassIndex">RenderPass index</param>
|
||||
/// <returns>viewConfigurationType for certain renderPass. Return 0 if invalid renderPass.</returns>
|
||||
protected static int GetViewConfigurationTypeForRenderPass(int renderPassIndex) =>
|
||||
Internal_GetViewTypeFromRenderIndex(renderPassIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Set the current XR Environment Blend Mode if it is supported by the active runtime. If not supported, fall back to the runtime preference.
|
||||
/// </summary>
|
||||
/// <param name="xrEnvironmentBlendMode">Environment Blend Mode (e.g.: Opaque = 1, Additive = 2, AlphaBlend = 3)</param>
|
||||
protected static void SetEnvironmentBlendMode(XrEnvironmentBlendMode xrEnvironmentBlendMode) =>
|
||||
Internal_SetEnvironmentBlendMode(xrEnvironmentBlendMode);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current XR Environment Blend Mode.
|
||||
/// </summary>
|
||||
/// <returns>Current XR Environment Blend Mode</returns>
|
||||
protected static XrEnvironmentBlendMode GetEnvironmentBlendMode() =>
|
||||
Internal_GetEnvironmentBlendMode();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// A Build-time validation rule.
|
||||
/// </summary>
|
||||
public class ValidationRule
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a validation rule for an OpenXRFeature.
|
||||
/// </summary>
|
||||
/// <param name="feature">Feature to create validation rule for</param>
|
||||
public ValidationRule(OpenXRFeature feature)
|
||||
{
|
||||
if (feature == null)
|
||||
throw new Exception("Invalid feature");
|
||||
this.feature = feature;
|
||||
}
|
||||
|
||||
internal ValidationRule()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Message describing the rule that will be showed to the developer if it fails.
|
||||
/// </summary>
|
||||
public string message;
|
||||
|
||||
/// <summary>
|
||||
/// Lambda function that returns true if validation passes, false if validation fails.
|
||||
/// </summary>
|
||||
public Func<bool> checkPredicate;
|
||||
|
||||
/// <summary>
|
||||
/// Lambda function that fixes the issue, if possible.
|
||||
/// </summary>
|
||||
public Action fixIt;
|
||||
|
||||
/// <summary>
|
||||
/// Text describing how the issue is fixed, shown in a tooltip.
|
||||
/// </summary>
|
||||
public string fixItMessage;
|
||||
|
||||
/// <summary>
|
||||
/// True if the fixIt Lambda function performs a function that is automatic and does not require user input. If your fixIt
|
||||
/// function requires user input, set fixitAutomatic to false to prevent the fixIt method from being executed during fixAll
|
||||
/// </summary>
|
||||
public bool fixItAutomatic = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, failing the rule is treated as an error and stops the build.
|
||||
/// If false, failing the rule is treated as a warning and it doesn't stop the build. The developer has the option to correct the problem, but is not required to.
|
||||
/// </summary>
|
||||
public bool error;
|
||||
|
||||
/// <summary>
|
||||
/// If true, will deny the project from entering playmode in editor.
|
||||
/// If false, can still enter playmode in editor if this issue isn't fixed.
|
||||
/// </summary>
|
||||
public bool errorEnteringPlaymode;
|
||||
|
||||
/// <summary>
|
||||
/// Optional text to display in a help icon with the issue in the validator.
|
||||
/// </summary>
|
||||
public string helpText;
|
||||
|
||||
/// <summary>
|
||||
/// Optional link that will be opened if the help icon is clicked.
|
||||
/// </summary>
|
||||
public string helpLink;
|
||||
|
||||
/// <summary>
|
||||
/// Optional struct HighlighterFocusData used to create HighlighterFocus functionality.
|
||||
/// WindowTitle contains the name of the window tab to highlight in.
|
||||
/// SearchPhrase contains the text to be searched and highlighted.
|
||||
/// </summary>
|
||||
public HighlighterFocusData highlighterFocus { get; set; }
|
||||
public struct HighlighterFocusData
|
||||
{
|
||||
public string windowTitle { get; set; }
|
||||
public string searchText { get; set; }
|
||||
}
|
||||
|
||||
internal OpenXRFeature feature;
|
||||
|
||||
internal BuildTargetGroup buildTargetGroup = BuildTargetGroup.Unknown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows a feature to add to a list of validation rules which your feature will evaluate at build time.
|
||||
/// Details of the validation results can be found in OpenXRProjectValidation.
|
||||
/// </summary>
|
||||
/// <param name="rules">Your feature will check the rules in this list at build time. Add rules that you want your feature to check, and remove rules that you want your feature to ignore.</param>
|
||||
/// <param name="targetGroup">Build target group these validation rules will be evaluated for.</param>
|
||||
protected internal virtual void GetValidationChecks(List<ValidationRule> rules, BuildTargetGroup targetGroup)
|
||||
{
|
||||
}
|
||||
|
||||
internal static void GetFullValidationList(List<ValidationRule> rules, BuildTargetGroup targetGroup)
|
||||
{
|
||||
var openXrSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(targetGroup);
|
||||
if (openXrSettings == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tempList = new List<ValidationRule>();
|
||||
foreach (var feature in openXrSettings.features)
|
||||
{
|
||||
if (feature != null)
|
||||
{
|
||||
feature.GetValidationChecks(tempList, targetGroup);
|
||||
rules.AddRange(tempList);
|
||||
tempList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GetValidationList(List<ValidationRule> rules, BuildTargetGroup targetGroup)
|
||||
{
|
||||
var openXrSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(targetGroup);
|
||||
if (openXrSettings == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var features = openXrSettings.features.Where(f => f != null)
|
||||
.OrderByDescending(f => f.priority)
|
||||
.ThenBy(f => f.nameUi);
|
||||
foreach (var feature in features)
|
||||
{
|
||||
if (feature != null && feature.enabled)
|
||||
feature.GetValidationChecks(rules, targetGroup);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Creates a subsystem based on a given a list of descriptors and a specific subsystem id.
|
||||
/// Promoted to public for extensions.
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="TDescriptor">The descriptor type being passed in</typeparam>
|
||||
/// <typeparam name="TSubsystem">The subsystem type being requested</typeparam>
|
||||
/// <param name="descriptors">List of TDescriptor instances to use for subsystem matching</param>
|
||||
/// <param name="id">The identifier key of the particular subsystem implementation being requested</param>
|
||||
protected void CreateSubsystem<TDescriptor, TSubsystem>(List<TDescriptor> descriptors, string id)
|
||||
where TDescriptor : ISubsystemDescriptor
|
||||
where TSubsystem : ISubsystem
|
||||
{
|
||||
if (OpenXRLoaderBase.Instance == null)
|
||||
{
|
||||
Debug.LogError("CreateSubsystem called before loader was initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenXRLoaderBase.Instance.CreateSubsystem<TDescriptor, TSubsystem>(descriptors, id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a subsystem instance of a given type. Subsystem is assumed to already be loaded from
|
||||
/// a previous call to CreateSubsystem.
|
||||
/// Promoted to public for extensions.
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="T">A subclass of <see cref="ISubsystem"/></typeparam>
|
||||
protected void StartSubsystem<T>() where T : class, ISubsystem
|
||||
{
|
||||
if (OpenXRLoaderBase.Instance == null)
|
||||
{
|
||||
Debug.LogError("StartSubsystem called before loader was initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenXRLoaderBase.Instance.StartSubsystem<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a subsystem instance of a given type. Subsystem is assumed to already be loaded from
|
||||
/// a previous call to CreateSubsystem.
|
||||
/// Promoted to public for extensions.
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="T">A subclass of <see cref="ISubsystem"/></typeparam>
|
||||
protected void StopSubsystem<T>() where T : class, ISubsystem
|
||||
{
|
||||
if (OpenXRLoaderBase.Instance == null)
|
||||
{
|
||||
Debug.LogError("StopSubsystem called before loader was initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenXRLoaderBase.Instance.StopSubsystem<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys a subsystem instance of a given type. Subsystem is assumed to already be loaded from
|
||||
/// a previous call to CreateSubsystem.
|
||||
/// Promoted to public for extensions.
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="T">A subclass of <see cref="ISubsystem"/></typeparam>
|
||||
protected void DestroySubsystem<T>() where T : class, ISubsystem
|
||||
{
|
||||
if (OpenXRLoaderBase.Instance == null)
|
||||
{
|
||||
Debug.LogError("DestroySubsystem called before loader was initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenXRLoaderBase.Instance.DestroySubsystem<T>();
|
||||
}
|
||||
|
||||
/// <summary>Called when the object is loaded.</summary>
|
||||
/// <remarks>
|
||||
/// Additional information:
|
||||
/// <a href="https://docs.unity3d.com/ScriptReference/ScriptableObject.OnEnable.html">ScriptableObject.OnEnable</a>
|
||||
/// </remarks>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Called when the object is loaded.</summary>
|
||||
/// <remarks>
|
||||
/// Additional information:
|
||||
/// <a href="https://docs.unity3d.com/ScriptReference/ScriptableObject.OnDisable.html">ScriptableObject.OnDisable</a>
|
||||
/// </remarks>
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
// Virtual for future expansion and to match OnEnable
|
||||
}
|
||||
|
||||
/// <summary>Called when the object is loaded.</summary>
|
||||
/// <remarks>
|
||||
/// Additional information:
|
||||
/// <a href="https://docs.unity3d.com/ScriptReference/ScriptableObject.Awake.html">ScriptableObject.Awake</a>
|
||||
/// </remarks>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
}
|
||||
|
||||
internal enum LoaderEvent
|
||||
{
|
||||
SubsystemCreate,
|
||||
SubsystemDestroy,
|
||||
SubsystemStart,
|
||||
SubsystemStop,
|
||||
}
|
||||
|
||||
internal static bool ReceiveLoaderEvent(OpenXRLoaderBase loader, LoaderEvent e)
|
||||
{
|
||||
var instance = OpenXRSettings.Instance;
|
||||
if (instance == null)
|
||||
return true;
|
||||
|
||||
foreach (var feature in instance.features)
|
||||
{
|
||||
if (feature == null || !feature.enabled)
|
||||
continue;
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case LoaderEvent.SubsystemCreate:
|
||||
feature.OnSubsystemCreate();
|
||||
break;
|
||||
case LoaderEvent.SubsystemDestroy:
|
||||
feature.OnSubsystemDestroy();
|
||||
break;
|
||||
case LoaderEvent.SubsystemStart:
|
||||
feature.OnSubsystemStart();
|
||||
break;
|
||||
case LoaderEvent.SubsystemStop:
|
||||
feature.OnSubsystemStop();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(e), e, null);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Must be kept in sync with unity_type.h ScriptEvents
|
||||
internal enum NativeEvent
|
||||
{
|
||||
// Setup
|
||||
XrSetupConfigValues,
|
||||
XrSystemIdChanged,
|
||||
XrInstanceChanged,
|
||||
XrSessionChanged,
|
||||
XrBeginSession,
|
||||
|
||||
// Runtime
|
||||
XrSessionStateChanged,
|
||||
XrChangedSpaceApp,
|
||||
|
||||
// Shutdown
|
||||
XrEndSession,
|
||||
XrDestroySession,
|
||||
XrDestroyInstance,
|
||||
|
||||
// General Session Events
|
||||
XrIdle,
|
||||
XrReady,
|
||||
XrSynchronized,
|
||||
XrVisible,
|
||||
XrFocused,
|
||||
XrStopping,
|
||||
XrExiting,
|
||||
XrLossPending,
|
||||
XrInstanceLossPending,
|
||||
XrRestartRequested,
|
||||
XrRequestRestartLoop,
|
||||
XrRequestGetSystemLoop,
|
||||
};
|
||||
|
||||
internal static void ReceiveNativeEvent(NativeEvent e, ulong payload)
|
||||
{
|
||||
if (null == OpenXRSettings.Instance)
|
||||
return;
|
||||
|
||||
foreach (var feature in OpenXRSettings.Instance.features)
|
||||
{
|
||||
if (feature == null || !feature.enabled)
|
||||
continue;
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case NativeEvent.XrSetupConfigValues:
|
||||
feature.OnFormFactorChange(Internal_GetFormFactor());
|
||||
feature.OnEnvironmentBlendModeChange(Internal_GetEnvironmentBlendMode());
|
||||
feature.OnViewConfigurationTypeChange(Internal_GetViewConfigurationType());
|
||||
break;
|
||||
|
||||
case NativeEvent.XrSystemIdChanged:
|
||||
feature.OnSystemChange(payload);
|
||||
break;
|
||||
case NativeEvent.XrInstanceChanged:
|
||||
feature.failedInitialization = !feature.OnInstanceCreate(payload);
|
||||
requiredFeatureFailed |= (feature.required && feature.failedInitialization);
|
||||
break;
|
||||
case NativeEvent.XrSessionChanged:
|
||||
feature.OnSessionCreate(payload);
|
||||
break;
|
||||
case NativeEvent.XrBeginSession:
|
||||
feature.OnSessionBegin(payload);
|
||||
break;
|
||||
case NativeEvent.XrChangedSpaceApp:
|
||||
feature.OnAppSpaceChange(payload);
|
||||
break;
|
||||
case NativeEvent.XrSessionStateChanged:
|
||||
Internal_GetSessionState(out var oldState, out var newState);
|
||||
feature.OnSessionStateChange(oldState, newState);
|
||||
break;
|
||||
case NativeEvent.XrEndSession:
|
||||
feature.OnSessionEnd(payload);
|
||||
break;
|
||||
case NativeEvent.XrExiting:
|
||||
feature.OnSessionExiting(payload);
|
||||
break;
|
||||
case NativeEvent.XrDestroySession:
|
||||
feature.OnSessionDestroy(payload);
|
||||
break;
|
||||
case NativeEvent.XrDestroyInstance:
|
||||
feature.OnInstanceDestroy(payload);
|
||||
break;
|
||||
case NativeEvent.XrLossPending:
|
||||
feature.OnSessionLossPending(payload);
|
||||
break;
|
||||
case NativeEvent.XrInstanceLossPending:
|
||||
feature.OnInstanceLossPending(payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
requiredFeatureFailed = false;
|
||||
|
||||
var instance = OpenXRSettings.Instance;
|
||||
if (instance == null || instance.features == null)
|
||||
return;
|
||||
|
||||
foreach (var feature in instance.features)
|
||||
if (feature != null)
|
||||
feature.failedInitialization = false;
|
||||
}
|
||||
|
||||
internal static void HookGetInstanceProcAddr()
|
||||
{
|
||||
var procAddr = Internal_GetProcAddressPtr(true);
|
||||
|
||||
var instance = OpenXRSettings.Instance;
|
||||
if (instance != null && instance.features != null)
|
||||
{
|
||||
// Hook the features in reverse priority order to ensure the highest priority feature is
|
||||
// hooked last. This will ensure the highest priority feature is called first in the chain.
|
||||
for (var featureIndex = instance.features.Length - 1; featureIndex >= 0; featureIndex--)
|
||||
{
|
||||
var feature = instance.features[featureIndex];
|
||||
if (feature == null || !feature.enabled)
|
||||
continue;
|
||||
|
||||
procAddr = feature.HookGetInstanceProcAddr(procAddr);
|
||||
}
|
||||
}
|
||||
|
||||
Internal_SetProcAddressPtrAndLoadStage1(procAddr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns XrAction handle bound to the given <see cref="UnityEngine.InputSystem.InputAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="inputAction">Action to retrieve XrAction handles for</param>
|
||||
/// <returns>XrAction handle bound to the given <see cref="UnityEngine.InputSystem.InputAction"/> or 0 if there is no bound XrAction</returns>
|
||||
protected ulong GetAction(InputAction inputAction) => OpenXRInput.GetActionHandle(inputAction);
|
||||
|
||||
/// <summary>
|
||||
/// Returns XrAction handle bound to the given device and usage.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to retrieve XrAction handles for</param>
|
||||
/// <param name="usage">Usage to retrieve XrAction handles for</param>
|
||||
/// <returns>XrAction handle bound to the given device and usage, or 0 if there is no bound XrAction</returns>
|
||||
protected ulong GetAction(InputDevice device, InputFeatureUsage usage) => OpenXRInput.GetActionHandle(device, usage);
|
||||
|
||||
/// <summary>
|
||||
/// Returns XrAction handle bound to the given device and usage.
|
||||
/// </summary>
|
||||
/// <param name="device">Device to retrieve XrAction handles for</param>
|
||||
/// <param name="usageName">Usage name to retrieve XrAction handles for</param>
|
||||
/// <returns>XrAction handle bound to the given device and usage, or 0 if there is no bound XrAction</returns>
|
||||
protected ulong GetAction(InputDevice device, string usageName) => OpenXRInput.GetActionHandle(device, usageName);
|
||||
|
||||
/// <summary>
|
||||
/// Flags that control various options and behaviors on registered stats.
|
||||
/// </summary>
|
||||
[System.Flags]
|
||||
protected internal enum StatFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// Stat will have no special options or behaviors
|
||||
/// </summary>
|
||||
StatOptionNone = 0,
|
||||
/// <summary>
|
||||
/// Stat will clear to 0.0f at the beginning of every frame
|
||||
/// </summary>
|
||||
ClearOnUpdate = 1 << 0,
|
||||
/// <summary>
|
||||
/// Stat will have all special options and behaviors
|
||||
/// </summary>
|
||||
All = (1 << 1) - 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an OpenXR statistic with the given name and flags.
|
||||
/// This method is not thread safe, so it should only be called at OnInstanceCreate.
|
||||
/// </summary>
|
||||
/// <param name="statName">String identifier for the statistic.</param>
|
||||
/// <param name="statFlags">Properties to be applied to the statistic.</param>
|
||||
/// <returns>Stat Id</returns>
|
||||
protected internal static ulong RegisterStatsDescriptor(string statName, StatFlags statFlags)
|
||||
{
|
||||
return runtime_RegisterStatsDescriptor(statName, statFlags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a float value to a registered statistic. Its thread safe.
|
||||
/// </summary>
|
||||
/// <param name="statId">Identifier of the previously registered statistic.</param>
|
||||
/// <param name="value">Float value to be assigned to the stat.</param>
|
||||
protected internal static void SetStatAsFloat(ulong statId, float value)
|
||||
{
|
||||
runtime_SetStatAsFloat(statId, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns an unsigned integer value to a registered statistic. It is thread safe.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// IMPORTANT: Due to limitations in native code, values over 16777216 (1<<24) might not be reflected accurately.
|
||||
/// </remarks>
|
||||
/// <param name="statId">Identifier of the previously registered statistic.</param>
|
||||
/// <param name="value">Unsigned integer value to be assigned to the stat.</param>
|
||||
protected internal static void SetStatAsUInt(ulong statId, uint value)
|
||||
{
|
||||
runtime_SetStatAsUInt(statId, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a921ca457a309d94c96e7d15a0df0554
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
|
||||
#if UNITY_EDITOR || PACKAGE_DOCS_GENERATION
|
||||
namespace UnityEditor.XR.OpenXR.Features
|
||||
{
|
||||
public class FeatureCategory
|
||||
{
|
||||
public const string Default = "";
|
||||
public const string Feature = "Feature";
|
||||
public const string Interaction = "Interaction";
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class OpenXRFeatureAttribute : Attribute
|
||||
{
|
||||
internal class CopyFieldAttribute : Attribute
|
||||
{
|
||||
public string FieldName;
|
||||
public CopyFieldAttribute(string fieldName)
|
||||
{
|
||||
FieldName = fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feature name to show in the feature configuration UI.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.nameUi))] public string UiName;
|
||||
|
||||
/// <summary>
|
||||
/// Hide this feature from the UI.
|
||||
/// </summary>
|
||||
public bool Hidden;
|
||||
|
||||
/// <summary>
|
||||
/// Feature description to show in the UI.
|
||||
/// </summary>
|
||||
public string Desc;
|
||||
|
||||
/// <summary>
|
||||
/// OpenXR runtime extension strings that need to be enabled to use this extension.
|
||||
/// If these extensions can't be enabled, a message will be logged, but execution will continue.
|
||||
/// Can contain multiple extensions separated by spaces.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.openxrExtensionStrings))] public string OpenxrExtensionStrings;
|
||||
|
||||
/// <summary>
|
||||
/// Company that created the feature, shown in the feature configuration UI.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.company))] public string Company;
|
||||
|
||||
/// <summary>
|
||||
/// Link to the feature documentation. The help button in the UI opens this link in a web browser.
|
||||
/// </summary>
|
||||
public string DocumentationLink;
|
||||
|
||||
/// <summary>
|
||||
/// Feature version.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.version))] public string Version;
|
||||
|
||||
/// <summary>
|
||||
/// BuildTargets in this list use a custom runtime loader (that is, openxr_loader.dll).
|
||||
/// Only one feature per platform can have a custom runtime loader.
|
||||
/// Unity will skip copying the default loader to the build and use this feature's loader instead on these platforms.
|
||||
/// Loader must be placed alongside the OpenXRFeature script or in a subfolder of it.
|
||||
/// </summary>
|
||||
public BuildTarget[] CustomRuntimeLoaderBuildTargets;
|
||||
|
||||
/// <summary>
|
||||
/// BuildTargetsGroups that this feature supports. The feature will only be shown or included on these platforms.
|
||||
/// </summary>
|
||||
public BuildTargetGroup[] BuildTargetGroups;
|
||||
|
||||
/// <summary>
|
||||
/// Feature category.
|
||||
/// </summary>
|
||||
public string Category = "";
|
||||
|
||||
/// <summary>
|
||||
/// True if this feature is required, false otherwise.
|
||||
/// Required features will cause the loader to fail to initialize if they fail to initialize or start.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.required))] public bool Required = false;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the order in which the feature will be called in both the GetInstanceProcAddr hook list and
|
||||
/// when events such as OnInstanceCreate are called. Higher priority features will hook after lower priority features and
|
||||
/// be called first in the event list.
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.priority))] public int Priority = 0;
|
||||
|
||||
/// <summary>
|
||||
/// A well known string id for this feature. It is recommended that that id be in reverse DNS naming format (com.foo.bar.feature).
|
||||
/// </summary>
|
||||
[CopyField(nameof(OpenXRFeature.featureIdInternal))] public string FeatureId = "";
|
||||
|
||||
|
||||
internal static readonly System.Text.RegularExpressions.Regex k_PackageVersionRegex = new System.Text.RegularExpressions.Regex(@"(\d*\.\d*)\..*");
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the OpenXR internal documentation link. This is necessary because the documentation link was made public in the
|
||||
/// Costants class which prevents it from being alterned in anything but a major revision. This method will patch up the documentation links
|
||||
/// as needed as long as they are internal openxr documentation links.
|
||||
/// </summary>
|
||||
internal string InternalDocumentationLink
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(DocumentationLink))
|
||||
return DocumentationLink;
|
||||
|
||||
// Update the version if needed
|
||||
if (DocumentationLink.StartsWith(Constants.k_DocumentationManualURL))
|
||||
{
|
||||
var version = PackageManager.PackageInfo.FindForAssembly(typeof(OpenXRFeatureAttribute).Assembly)?.version;
|
||||
var majorminor = k_PackageVersionRegex.Match(version).Groups[1].Value;
|
||||
DocumentationLink = DocumentationLink.Replace("1.0", majorminor);
|
||||
}
|
||||
|
||||
return DocumentationLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f8c88249c4adc844ba1a147fcaf83e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.XR.OpenXR.NativeTypes;
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features
|
||||
{
|
||||
public abstract partial class OpenXRFeature
|
||||
{
|
||||
const string Library = "UnityOpenXR";
|
||||
|
||||
[DllImport(Library, EntryPoint = "Internal_PathToString")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
static extern bool Internal_PathToStringPtr(ulong pathId, out IntPtr path);
|
||||
|
||||
[DllImport(Library, EntryPoint = "Internal_StringToPath")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
static extern bool Internal_StringToPath([MarshalAs(UnmanagedType.LPStr)] string str, out ulong pathId);
|
||||
|
||||
[DllImport(Library, EntryPoint = "Internal_GetCurrentInteractionProfile")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
static extern bool Internal_GetCurrentInteractionProfile(ulong pathId, out ulong interactionProfile);
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_GetFormFactor")]
|
||||
static extern int Internal_GetFormFactor();
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_GetViewConfigurationType")]
|
||||
static extern int Internal_GetViewConfigurationType();
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_GetViewTypeFromRenderIndex")]
|
||||
static extern int Internal_GetViewTypeFromRenderIndex(int renderPassIndex);
|
||||
|
||||
[DllImport(Library, EntryPoint = "OpenXRInputProvider_GetXRSession")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool Internal_GetXRSession(out ulong xrSession);
|
||||
|
||||
[DllImport(Library, EntryPoint = "session_GetSessionState")]
|
||||
static extern void Internal_GetSessionState(out int oldState, out int newState);
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_GetEnvironmentBlendMode")]
|
||||
static extern XrEnvironmentBlendMode Internal_GetEnvironmentBlendMode();
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_SetEnvironmentBlendMode")]
|
||||
static extern void Internal_SetEnvironmentBlendMode(XrEnvironmentBlendMode xrEnvironmentBlendMode);
|
||||
|
||||
[DllImport(Library, EntryPoint = "OpenXRInputProvider_GetAppSpace")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool Internal_GetAppSpace(out ulong appSpace);
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_GetProcAddressPtr")]
|
||||
internal static extern IntPtr Internal_GetProcAddressPtr([MarshalAs(UnmanagedType.I1)] bool loaderDefault);
|
||||
|
||||
[DllImport(Library, EntryPoint = "NativeConfig_SetProcAddressPtrAndLoadStage1")]
|
||||
internal static extern void Internal_SetProcAddressPtrAndLoadStage1(IntPtr func);
|
||||
|
||||
[DllImport(Library)]
|
||||
internal static extern ulong runtime_RegisterStatsDescriptor(string statName, StatFlags statFlags);
|
||||
|
||||
[DllImport(Library)]
|
||||
internal static extern void runtime_SetStatAsFloat(ulong statId, float value);
|
||||
|
||||
[DllImport(Library)]
|
||||
internal static extern void runtime_SetStatAsUInt(ulong statId, uint value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1205eddf78bff947b6e9f98809dbe33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
[assembly: InternalsVisibleTo("UnityEditor.XR.OpenXR.Tests")]
|
||||
namespace UnityEngine.XR.OpenXR
|
||||
{
|
||||
public partial class OpenXRSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// All known features.
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("extensions")]
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
internal OpenXRFeature[] features = { };
|
||||
|
||||
/// <summary>
|
||||
/// Number of available features.
|
||||
/// </summary>
|
||||
public int featureCount => features.Length;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first feature that matches the given type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFeature">Type of the feature to retrieve</typeparam>
|
||||
/// <returns>Feature by type</returns>
|
||||
public TFeature GetFeature<TFeature>() where TFeature : OpenXRFeature => (TFeature)GetFeature(typeof(TFeature));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first feature that matches the given type.
|
||||
/// </summary>
|
||||
/// <param name="featureType">Type of the feature to return</param>
|
||||
/// <returns>Feature by type</returns>
|
||||
public OpenXRFeature GetFeature(Type featureType)
|
||||
{
|
||||
foreach (var feature in features)
|
||||
if (featureType.IsInstanceOfType(feature))
|
||||
return feature;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all features of a given type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFeature">Type of the feature to retrieve</typeparam>
|
||||
/// <returns>All components of Type</returns>
|
||||
public OpenXRFeature[] GetFeatures<TFeature>() => GetFeatures(typeof(TFeature));
|
||||
|
||||
/// <summary>
|
||||
/// Returns all features of Type.
|
||||
/// </summary>
|
||||
/// <param name="featureType">Type of the feature to retrieve</param>
|
||||
/// <returns>All components of Type</returns>
|
||||
public OpenXRFeature[] GetFeatures(Type featureType)
|
||||
{
|
||||
var result = new List<OpenXRFeature>();
|
||||
foreach (var feature in features)
|
||||
if (featureType.IsInstanceOfType(feature))
|
||||
result.Add(feature);
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all features of a given type.
|
||||
/// </summary>
|
||||
/// <param name="featuresOut">Output list of features</param>
|
||||
/// <typeparam name="TFeature">Feature type</typeparam>
|
||||
/// <returns>Number of features returned</returns>
|
||||
public int GetFeatures<TFeature>(List<TFeature> featuresOut) where TFeature : OpenXRFeature
|
||||
{
|
||||
featuresOut.Clear();
|
||||
foreach (var feature in features)
|
||||
if (feature is TFeature xrFeature)
|
||||
featuresOut.Add(xrFeature);
|
||||
|
||||
return featuresOut.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all features of a given type.
|
||||
/// </summary>
|
||||
/// <param name="featureType">Type of the feature to retrieve</param>
|
||||
/// <param name="featuresOut">Output list of features</param>
|
||||
/// <returns>Number of features returned</returns>
|
||||
public int GetFeatures(Type featureType, List<OpenXRFeature> featuresOut)
|
||||
{
|
||||
featuresOut.Clear();
|
||||
foreach (var feature in features)
|
||||
if (featureType.IsInstanceOfType(feature))
|
||||
featuresOut.Add(feature);
|
||||
|
||||
return featuresOut.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all features.
|
||||
/// </summary>
|
||||
/// <returns>All features</returns>
|
||||
public OpenXRFeature[] GetFeatures() => (OpenXRFeature[])features?.Clone() ?? new OpenXRFeature[0];
|
||||
|
||||
/// <summary>
|
||||
/// Return all features.
|
||||
/// </summary>
|
||||
/// <param name="featuresOut">Output list of features</param>
|
||||
/// <returns>Number of features returned</returns>
|
||||
public int GetFeatures(List<OpenXRFeature> featuresOut)
|
||||
{
|
||||
featuresOut.Clear();
|
||||
featuresOut.AddRange(features);
|
||||
return featuresOut.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07304509a07b28c42b25d3afb271331a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,417 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.Management;
|
||||
using UnityEngine.XR.Management;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.XR.OpenXR.Features
|
||||
{
|
||||
/// <summary>
|
||||
/// A Unity OpenXR Interaction feature.
|
||||
/// This class can be inherited from to add a custom action mapping for OpenXR.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class OpenXRInteractionFeature : OpenXRFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// Temporary static list used for action map creation
|
||||
/// </summary>
|
||||
private static List<ActionMapConfig> m_CreatedActionMaps = null;
|
||||
private static Dictionary<InteractionProfileType, Dictionary<string, bool>> m_InteractionProfileEnabledMaps = new Dictionary<InteractionProfileType, Dictionary<string, bool>>();
|
||||
|
||||
/// <summary>
|
||||
/// Flag that indicates this feature or profile is additive and its binding paths will be added to other non-additive profiles if enabled.
|
||||
/// </summary>
|
||||
internal virtual bool IsAdditive => false;
|
||||
|
||||
/// <summary>
|
||||
/// The underlying type of an OpenXR action. This enumeration contains all supported control types within OpenXR. This is used when declaring actions in OpenXR with XrAction/>.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
protected internal enum ActionType
|
||||
{
|
||||
/// <summary>A binary (on/off) action type. Represented by ButtonControl in the Input System or Boolean in XR.InputDevice.</summary>
|
||||
Binary,
|
||||
/// <summary>A single Axis float action type. Represented by an AxisControl in the InputSystem or a float in XR.InputDevice.</summary>
|
||||
Axis1D,
|
||||
/// <summary>A two-dimensional float action type. Represented by a Vector2Control in the InputSystem or Vector2 in XR.InputDevice.</summary>
|
||||
Axis2D,
|
||||
/// <summary>A position and rotation in three-dimensional space. Represented by a PoseControl in the InputSystem, and a series of controls (boolean to represent if it's being tracked or not, unsigned integer for which fields are available, Vector3 for position, Quaternion for rotation) in XR.InputDevice.</summary>
|
||||
Pose,
|
||||
/// <summary>This control represents an output motor. Usable as sequential channels (first declared is channel 0, second is 1, etc...) in both the Input System and XR.InputDevice haptic APIs.</summary>
|
||||
Vibrate,
|
||||
/// <summary>A value representing the total number of ActionTypes available. This can be used to check if an ActionType value is a valid ActionType.</summary>
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information sent to OpenXR about specific, physical control on an input device. Used to identify what an action is bound to (that is, which physical control will trigger that action).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
protected internal class ActionBinding
|
||||
{
|
||||
/// <summary>OpenXR interaction profile name</summary>
|
||||
public string interactionProfileName;
|
||||
|
||||
/// <summary>OpenXR path for the interaction</summary>
|
||||
public string interactionPath;
|
||||
|
||||
/// <summary>Optional OpenXR user paths <see cref="UserPaths"/></summary>
|
||||
public List<string> userPaths;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declares an abstract input source bound to multiple physical input controls. XrActions are commonly contained within an ActionMapConfig as a grouped series of abstract, remappable inputs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
protected internal class ActionConfig
|
||||
{
|
||||
/// <summary>The name of the action, reported into the InputSystem as the name of the control that represents the input data for this action. This name can only contain a-z lower case letters.</summary>
|
||||
public string name;
|
||||
|
||||
/// <summary>The type of data this action will report. <see cref="ActionType"/></summary>
|
||||
public ActionType type;
|
||||
|
||||
/// <summary>Human readable name for the action</summary>
|
||||
public string localizedName;
|
||||
|
||||
/// <summary>The underlying physical input controls to use as the value for this action</summary>
|
||||
public List<ActionBinding> bindings;
|
||||
|
||||
/// <summary>These will be tagged onto <see cref="UnityEngine.XR.InputDevice"/> features. See <see cref="UnityEngine.XR.InputDevice.TryGetFeatureValue"/></summary>
|
||||
public List<string> usages;
|
||||
|
||||
/// <summary>Tag to determine if certain action is additive and could be added to the existing profiles</summary>
|
||||
public bool isAdditive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information sent to the OpenXR runtime to identify how to map a <see cref="UnityEngine.XR.InputDevice"/> or <see cref="UnityEngine.InputSystem.InputDevice"/> to an underlying OpenXR user path.
|
||||
/// </summary>
|
||||
protected internal class DeviceConfig
|
||||
{
|
||||
/// <summary>The <see cref="InputDeviceCharacteristics"/> for the <see cref="UnityEngine.XR.InputDevice"/> that will represent this ActionMapConfig. See <see cref="UnityEngine.XR.InputDevice.characteristics"/></summary>
|
||||
public InputDeviceCharacteristics characteristics;
|
||||
|
||||
/// <summary>OpenXR user path that this device maps to. <see cref="UserPaths"/></summary>
|
||||
public string userPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a mapping of between the Unity input system and OpenXR.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
protected internal class ActionMapConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the action map
|
||||
/// </summary>
|
||||
public string name;
|
||||
|
||||
/// <summary>
|
||||
/// Human readable name of the OpenXR user path that this device maps to.
|
||||
/// </summary>
|
||||
public string localizedName;
|
||||
|
||||
/// <summary>
|
||||
/// List of devices to configure
|
||||
/// </summary>
|
||||
public List<DeviceConfig> deviceInfos;
|
||||
|
||||
/// <summary>
|
||||
/// List of actions to configure
|
||||
/// </summary>
|
||||
public List<ActionConfig> actions;
|
||||
|
||||
/// <summary>
|
||||
/// OpenXR interaction profile to use for this action map
|
||||
/// </summary>
|
||||
public string desiredInteractionProfile;
|
||||
|
||||
/// <summary>
|
||||
/// Name of the manufacturer providing this action map
|
||||
/// </summary>
|
||||
public string manufacturer;
|
||||
|
||||
/// <summary>
|
||||
/// Serial number of the device
|
||||
/// </summary>
|
||||
public string serialNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common OpenXR user path definitions.
|
||||
/// See the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#semantic-path-user) for more information.
|
||||
/// </summary>
|
||||
public static class UserPaths
|
||||
{
|
||||
/// <summary>
|
||||
/// Path for user left hand
|
||||
/// </summary>
|
||||
public const string leftHand = "/user/hand/left";
|
||||
|
||||
/// <summary>
|
||||
/// Path for user right hand
|
||||
/// </summary>
|
||||
public const string rightHand = "/user/hand/right";
|
||||
|
||||
/// <summary>
|
||||
/// Path for user head
|
||||
/// </summary>
|
||||
public const string head = "/user/head";
|
||||
|
||||
/// <summary>
|
||||
/// Path for user gamepad
|
||||
/// </summary>
|
||||
public const string gamepad = "/user/gamepad";
|
||||
|
||||
/// <summary>
|
||||
/// Path for user treadmill
|
||||
/// </summary>
|
||||
public const string treadmill = "/user/treadmill";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags used to indicate Interaction profile type
|
||||
/// </summary>
|
||||
public enum InteractionProfileType
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction profile derived from InputDevice class
|
||||
/// </summary>
|
||||
Device,
|
||||
/// <summary>
|
||||
/// Interaction profile derived from XRController class
|
||||
/// </summary>
|
||||
XRController
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a device layout with the Unity Input System.
|
||||
/// Called whenever this interaction profile is enabled in the Editor.
|
||||
/// </summary>
|
||||
protected virtual void RegisterDeviceLayout()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a device layout from the Unity Input System.
|
||||
/// Called whenever this interaction profile is disabled in the Editor.
|
||||
/// </summary>
|
||||
protected virtual void UnregisterDeviceLayout()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register action maps for this device with the OpenXR Runtime.
|
||||
/// Called at runtime before Start.
|
||||
/// </summary>
|
||||
protected virtual void RegisterActionMapsWithRuntime()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override bool OnInstanceCreate(ulong xrSession)
|
||||
{
|
||||
RegisterDeviceLayout();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return interaction profile type. Default type is XRController. Override this if interactionProfile is not derived from XRController class.
|
||||
/// </summary>
|
||||
/// <returns>Interaction profile type.</returns>
|
||||
protected virtual InteractionProfileType GetInteractionProfileType() => InteractionProfileType.XRController;
|
||||
|
||||
/// <summary>
|
||||
/// Return device layout name string used for register layouts in inputSystem.
|
||||
/// </summary>
|
||||
/// <returns>Device layout string.</returns>
|
||||
protected virtual string GetDeviceLayoutName() => "";
|
||||
|
||||
/// <summary>
|
||||
/// Request the feature create its action maps
|
||||
/// </summary>
|
||||
/// <param name="configs">Target list for the action maps</param>
|
||||
internal void CreateActionMaps(List<ActionMapConfig> configs)
|
||||
{
|
||||
m_CreatedActionMaps = configs;
|
||||
RegisterActionMapsWithRuntime();
|
||||
m_CreatedActionMaps = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an action map to the Unity Input System.
|
||||
///
|
||||
/// This method must be called from within the RegisterActionMapsWithRuntime method.
|
||||
/// </summary>
|
||||
/// <param name="map">Action map to add</param>
|
||||
protected void AddActionMap(ActionMapConfig map)
|
||||
{
|
||||
if (null == map)
|
||||
throw new ArgumentNullException("map");
|
||||
|
||||
if (null == m_CreatedActionMaps)
|
||||
throw new InvalidOperationException("ActionMap must be added from within the RegisterActionMapsWithRuntime method");
|
||||
|
||||
m_CreatedActionMaps.Add(map);
|
||||
}
|
||||
|
||||
internal virtual void AddAdditiveActions(List<OpenXRInteractionFeature.ActionMapConfig> actionMaps, ActionMapConfig additiveMap)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle enabled state change
|
||||
/// </summary>
|
||||
protected internal override void OnEnabledChange()
|
||||
{
|
||||
base.OnEnabledChange();
|
||||
#if UNITY_EDITOR && INPUT_SYSTEM_BINDING_VALIDATOR
|
||||
var packageSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
if (null == packageSettings)
|
||||
return;
|
||||
|
||||
foreach (var feature in packageSettings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
var profileType = ((OpenXRInteractionFeature) feature).GetInteractionProfileType();
|
||||
string deviceLayoutName = ((OpenXRInteractionFeature) feature).GetDeviceLayoutName();
|
||||
deviceLayoutName = "<" + deviceLayoutName + ">";
|
||||
if (m_InteractionProfileEnabledMaps.ContainsKey(profileType) && m_InteractionProfileEnabledMaps[profileType].ContainsKey(deviceLayoutName))
|
||||
m_InteractionProfileEnabledMaps[profileType][deviceLayoutName] = feature.enabled;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void RegisterLayouts()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
#if UNITY_EDITOR
|
||||
var packageSettings = OpenXRSettings.GetSettingsForBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
if (null == packageSettings)
|
||||
return;
|
||||
#if INPUT_SYSTEM_BINDING_VALIDATOR
|
||||
m_InteractionProfileEnabledMaps.Clear();
|
||||
foreach (var feature in packageSettings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
//Register all the available profiles
|
||||
((OpenXRInteractionFeature) feature).RegisterDeviceLayout();
|
||||
|
||||
var profileType = ((OpenXRInteractionFeature) feature).GetInteractionProfileType();
|
||||
string deviceLayoutName = ((OpenXRInteractionFeature) feature).GetDeviceLayoutName();
|
||||
if (String.IsNullOrEmpty(deviceLayoutName))
|
||||
{
|
||||
Debug.LogWarningFormat("No GetDeviceLayoutName() override detected in {0}. Binding path validator for this interaction profile is not as effective. To fix, add GetDeviceLayoutName and GetInteractionProfileType override in this profile.", feature.nameUi);
|
||||
continue;
|
||||
}
|
||||
deviceLayoutName = "<" + deviceLayoutName + ">";
|
||||
if (!m_InteractionProfileEnabledMaps.ContainsKey(profileType))
|
||||
m_InteractionProfileEnabledMaps[profileType] = new Dictionary<string, bool>();
|
||||
|
||||
m_InteractionProfileEnabledMaps[profileType].Add(deviceLayoutName, feature.enabled);
|
||||
}
|
||||
InputSystem.InputSystem.customBindingPathValidators -= PathValidator;
|
||||
InputSystem.InputSystem.customBindingPathValidators += PathValidator;
|
||||
#else //#if INPUT_SYSTEM_BINDING_VALIDATOR
|
||||
foreach (var feature in packageSettings.GetFeatures<OpenXRInteractionFeature>())
|
||||
{
|
||||
//Register all the available profiles
|
||||
((OpenXRInteractionFeature)feature).RegisterDeviceLayout();
|
||||
}
|
||||
#endif //#if INPUT_SYSTEM_BINDING_VALIDATOR
|
||||
#else
|
||||
foreach (var feature in OpenXRSettings.Instance.GetFeatures<OpenXRInteractionFeature>())
|
||||
if (feature.enabled)
|
||||
((OpenXRInteractionFeature)feature).RegisterDeviceLayout();
|
||||
#endif //#if UNITY_EDITOR
|
||||
#endif //#if ENABLE_INPUT_SYSTEM
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR && INPUT_SYSTEM_BINDING_VALIDATOR
|
||||
internal static Action PathValidator(string bindingPath)
|
||||
{
|
||||
//case1: OpenXR plugin not enabled in XR management
|
||||
if (!OpenXRLoaderEnabledForSelectedBuildTarget(EditorUserBuildSettings.selectedBuildTargetGroup))
|
||||
return null;
|
||||
|
||||
string warningText = null;
|
||||
//case2: current bindingPath maps to XRController.
|
||||
if (bindingPath.StartsWith("<XRController>"))
|
||||
{
|
||||
if (!m_InteractionProfileEnabledMaps.ContainsKey(InteractionProfileType.XRController))
|
||||
return null;
|
||||
bool controllerProfileEnabled = false;
|
||||
foreach (var profile in m_InteractionProfileEnabledMaps[InteractionProfileType.XRController])
|
||||
{
|
||||
if (profile.Value)
|
||||
controllerProfileEnabled = true;
|
||||
}
|
||||
if (controllerProfileEnabled)
|
||||
return null;
|
||||
warningText = "This binding will be inactive because there are no enabled OpenXR interaction profiles.";
|
||||
}
|
||||
else
|
||||
{
|
||||
//case3: current bindingPath maps to specific OpenXR interaction profile
|
||||
//Only check for bindings that belongs to OpenXRInteractionFeature
|
||||
bool checkXRInteractionBinding = false;
|
||||
bool profileEnabled = false;
|
||||
foreach (var map in m_InteractionProfileEnabledMaps)
|
||||
{
|
||||
foreach (var profile in map.Value)
|
||||
{
|
||||
if (bindingPath.StartsWith(profile.Key, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
checkXRInteractionBinding = true;
|
||||
profileEnabled = profile.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkXRInteractionBinding)
|
||||
break;
|
||||
}
|
||||
if (!checkXRInteractionBinding || profileEnabled)
|
||||
return null;
|
||||
|
||||
warningText = "This binding will be inactive because it refers to a disabled OpenXR interaction profile.";
|
||||
}
|
||||
// Draw the warning information in the Binding Properties panel
|
||||
return () =>
|
||||
{
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label(EditorGUIUtility.IconContent("Warning@2x"), new GUIStyle(EditorStyles.label));
|
||||
GUILayout.Label(warningText, EditorStyles.wordWrappedLabel);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if(GUILayout.Button("Manage Interaction Profiles"))
|
||||
SettingsService.OpenProjectSettings("Project/XR Plug-in Management/OpenXR");
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.EndVertical();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal static bool OpenXRLoaderEnabledForSelectedBuildTarget(BuildTargetGroup targetGroup)
|
||||
{
|
||||
var settings =XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(targetGroup)?.AssignedSettings;
|
||||
if (!settings)
|
||||
return false;
|
||||
bool loaderFound = false;
|
||||
foreach (var activeLoader in settings.activeLoaders)
|
||||
{
|
||||
if (activeLoader as OpenXRLoader != null)
|
||||
{
|
||||
loaderFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return loaderFound;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08f06941bba688d4186b3d0d58406195
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user