上传YomovSDK

This commit is contained in:
Sora丶kong
2026-03-03 03:15:46 +08:00
parent 9096da7e6c
commit eb97f31065
6477 changed files with 1932208 additions and 3 deletions

View File

@@ -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);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c5b5af5107e35a43818d5411328bfc3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3cf79659a011bd419c7a2a30eb74e9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e5315f812f023cf4ebf26f7e5d2d70f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 274c02963f889a64e90bc2e596e21d13
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a24be4b5ebfe5f4d8ed1de9b25cb7aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5019471fb2174e5c852ecd4047163007
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f6bfdbcb316ed242b30a8798c9eb853
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b7365b139f7aec43b23d26b7a48b5a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c4b862ee14fb479fbfe5fffe655d3ed3
timeCreated: 1667676951

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f928d0d73a35f294fbe357ca17aa3547
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 761fdd4502cb7a84e9ec7a2b24f33f37
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: feeef8d85de8db242bdda70cc7ff5acd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f028123e2efe1d443875bc7609b4a98b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d6ccd3d0ef0f1d458e69421dccbdae1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: