// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled. #if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION using System; using System.Collections.Generic; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.Controls; using UnityEngine.XR; namespace UnityEngine.InputSystem.XR { /// /// A set of static utilities for registering XR Input Devices externally. /// public static class XRUtilities { /// /// A simple Regex pattern that allows InputDeviceMatchers to match to any version of the XRInput interface. /// public const string InterfaceMatchAnyVersion = "^(XRInput)"; /// /// The initial, now deprecated interface for XRInput. This version handles button packing for Android differently from current. /// public const string InterfaceV1 = "XRInput"; /// /// The current interface code sent with devices to identify as XRInput devices. /// public const string InterfaceCurrent = "XRInputV1"; } // Sync to UnityXRInputFeatureType in IUnityXRInput.h /// /// The type of data a exposes. /// public enum FeatureType { Custom = 0, Binary, DiscreteStates, Axis1D, Axis2D, Axis3D, Rotation, Hand, Bone, Eyes } /// /// Contextual strings that identify the contextual, cross-platform use that a feature represents. for a list of unity's built-in shared usages. /// #pragma warning disable 0649 [Serializable] public struct UsageHint { public string content; } //Sync to XRInputFeatureDefinition in XRInputDeviceDefinition.h /// /// Describes an individual input on a device, such as a trackpad, or button, or trigger. /// [Serializable] public struct XRFeatureDescriptor { /// /// The name of the feature. /// public string name; /// /// The uses that this feature should represent, such as trigger, or grip, or touchpad. /// public List usageHints; /// /// The type of data this feature exposes. /// public FeatureType featureType; /// /// The overall size of the feature. This is only filled in when the is . /// public uint customSize; } //Sync to XRInputDeviceDefinition in XRInputDeviceDefinition.h /// /// Describes an input device: what it can do and how it should be used. These are reported during device connection, and help identify devices and map input data to the right controls. /// [Serializable] public class XRDeviceDescriptor { /// /// The name of the device. /// public string deviceName; /// /// The manufacturer of the device. /// public string manufacturer; /// /// The serial number of the device. An empty string if no serial number is available. /// public string serialNumber; /// /// The capabilities of the device, used to help filter and identify devices that server a certain purpose (e.g. controller, or headset, or hardware tracker). /// public InputDeviceCharacteristics characteristics; /// /// The underlying deviceId, this can be used with to create a device. /// public int deviceId; /// /// A list of all input features. /// public List inputFeatures; /// /// Converts this structure to a JSON string. /// /// public string ToJson() { return JsonUtility.ToJson(this); } /// /// Converts a json string to a new . /// /// The JSON string containing data. /// A new public static XRDeviceDescriptor FromJson(string json) { return JsonUtility.FromJson(json); } } /// /// Represents a 3 dimensional, tracked bone within a hierarchy of other bones. /// public struct Bone { /// /// The index with the device's controls array where the parent bone resides. /// public uint m_ParentBoneIndex; /// /// The tracked position of the bone. /// public Vector3 m_Position; /// /// The tracked rotation of the bone. /// public Quaternion m_Rotation; /// /// The index with the device's controls array where the parent bone resides. /// public uint parentBoneIndex { get => m_ParentBoneIndex; set => m_ParentBoneIndex = value; } /// /// The tracked position of the bone. /// public Vector3 position { get => m_Position; set => m_Position = value; } /// /// The tracked rotation of the bone. /// public Quaternion rotation { get => m_Rotation; set => m_Rotation = value; } } /// /// Represents a pair of tracked eyes. /// public struct Eyes { /// /// The tracked position of the left eye. /// public Vector3 m_LeftEyePosition; /// /// The tracked rotation of the left eye. /// public Quaternion m_LeftEyeRotation; /// /// The tracked position of the right eye. /// public Vector3 m_RightEyePosition; /// /// The tracked rotation of the right eye. /// public Quaternion m_RightEyeRotation; /// /// The point in 3D space that the pair of eyes is looking. /// public Vector3 m_FixationPoint; /// /// The amount [0-1] the left eye is open or closed. 1.0 is fully open. /// public float m_LeftEyeOpenAmount; /// /// The amount [0-1] the right eye is open or closed. 1.0 is fully open. /// public float m_RightEyeOpenAmount; /// /// The tracked position of the left eye. /// public Vector3 leftEyePosition { get => m_LeftEyePosition; set => m_LeftEyePosition = value; } /// /// The tracked rotation of the left eye. /// public Quaternion leftEyeRotation { get => m_LeftEyeRotation; set => m_LeftEyeRotation = value; } /// /// The tracked position of the right eye. /// public Vector3 rightEyePosition { get => m_RightEyePosition; set => m_RightEyePosition = value; } /// /// The tracked rotation of the right eye. /// public Quaternion rightEyeRotation { get => m_RightEyeRotation; set => m_RightEyeRotation = value; } /// /// The point in 3D space that the pair of eyes is looking. /// public Vector3 fixationPoint { get => m_FixationPoint; set => m_FixationPoint = value; } /// /// The amount [0-1] the left eye is open or closed. 1.0 is fully open. /// public float leftEyeOpenAmount { get => m_LeftEyeOpenAmount; set => m_LeftEyeOpenAmount = value; } /// /// The amount [0-1] the right eye is open or closed. 1.0 is fully open. /// public float rightEyeOpenAmount { get => m_RightEyeOpenAmount; set => m_RightEyeOpenAmount = value; } } public class BoneControl : InputControl { [InputControl(offset = 0, displayName = "parentBoneIndex")] public IntegerControl parentBoneIndex { get; private set; } [InputControl(offset = 4, displayName = "Position")] public Vector3Control position { get; private set; } [InputControl(offset = 16, displayName = "Rotation")] public QuaternionControl rotation { get; private set; } protected override void FinishSetup() { parentBoneIndex = GetChildControl("parentBoneIndex"); position = GetChildControl("position"); rotation = GetChildControl("rotation"); base.FinishSetup(); } public override unsafe Bone ReadUnprocessedValueFromState(void* statePtr) { return new Bone() { parentBoneIndex = (uint)parentBoneIndex.ReadUnprocessedValueFromStateWithCaching(statePtr), position = position.ReadUnprocessedValueFromStateWithCaching(statePtr), rotation = rotation.ReadUnprocessedValueFromStateWithCaching(statePtr) }; } public override unsafe void WriteValueIntoState(Bone value, void* statePtr) { parentBoneIndex.WriteValueIntoState((int)value.parentBoneIndex, statePtr); position.WriteValueIntoState(value.position, statePtr); rotation.WriteValueIntoState(value.rotation, statePtr); } } public class EyesControl : InputControl { [InputControl(offset = 0, displayName = "LeftEyePosition")] public Vector3Control leftEyePosition { get; private set; } [InputControl(offset = 12, displayName = "LeftEyeRotation")] public QuaternionControl leftEyeRotation { get; private set; } [InputControl(offset = 28, displayName = "RightEyePosition")] public Vector3Control rightEyePosition { get; private set; } [InputControl(offset = 40, displayName = "RightEyeRotation")] public QuaternionControl rightEyeRotation { get; private set; } [InputControl(offset = 56, displayName = "FixationPoint")] public Vector3Control fixationPoint { get; private set; } [InputControl(offset = 68, displayName = "LeftEyeOpenAmount")] public AxisControl leftEyeOpenAmount { get; private set; } [InputControl(offset = 72, displayName = "RightEyeOpenAmount")] public AxisControl rightEyeOpenAmount { get; private set; } protected override void FinishSetup() { leftEyePosition = GetChildControl("leftEyePosition"); leftEyeRotation = GetChildControl("leftEyeRotation"); rightEyePosition = GetChildControl("rightEyePosition"); rightEyeRotation = GetChildControl("rightEyeRotation"); fixationPoint = GetChildControl("fixationPoint"); leftEyeOpenAmount = GetChildControl("leftEyeOpenAmount"); rightEyeOpenAmount = GetChildControl("rightEyeOpenAmount"); base.FinishSetup(); } public override unsafe Eyes ReadUnprocessedValueFromState(void* statePtr) { return new Eyes() { leftEyePosition = leftEyePosition.ReadUnprocessedValueFromStateWithCaching(statePtr), leftEyeRotation = leftEyeRotation.ReadUnprocessedValueFromStateWithCaching(statePtr), rightEyePosition = rightEyePosition.ReadUnprocessedValueFromStateWithCaching(statePtr), rightEyeRotation = rightEyeRotation.ReadUnprocessedValueFromStateWithCaching(statePtr), fixationPoint = fixationPoint.ReadUnprocessedValueFromStateWithCaching(statePtr), leftEyeOpenAmount = leftEyeOpenAmount.ReadUnprocessedValueFromStateWithCaching(statePtr), rightEyeOpenAmount = rightEyeOpenAmount.ReadUnprocessedValueFromStateWithCaching(statePtr) }; } public override unsafe void WriteValueIntoState(Eyes value, void* statePtr) { leftEyePosition.WriteValueIntoState(value.leftEyePosition, statePtr); leftEyeRotation.WriteValueIntoState(value.leftEyeRotation, statePtr); rightEyePosition.WriteValueIntoState(value.rightEyePosition, statePtr); rightEyeRotation.WriteValueIntoState(value.rightEyeRotation, statePtr); fixationPoint.WriteValueIntoState(value.fixationPoint, statePtr); leftEyeOpenAmount.WriteValueIntoState(value.leftEyeOpenAmount, statePtr); rightEyeOpenAmount.WriteValueIntoState(value.rightEyeOpenAmount, statePtr); } } #pragma warning restore 0649 /// /// A small helper class to aid in initializing and registering XR devices and layout builders. /// #if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION public #else internal #endif static class XRSupport { /// /// Registers all initial templates and the generalized layout builder with the InputSystem. /// public static void Initialize() { #if !UNITY_FORCE_INPUTSYSTEM_XR_OFF InputSystem.RegisterLayout("Pose"); InputSystem.RegisterLayout("Bone"); InputSystem.RegisterLayout("Eyes"); InputSystem.RegisterLayout(); InputSystem.RegisterLayout(); InputSystem.onFindLayoutForDevice += XRLayoutBuilder.OnFindLayoutForDevice; // Built-in layouts replaced by the com.unity.xr.windowsmr package. #if !DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("(Windows Mixed Reality HMD)|(Microsoft HoloLens)|(^(WindowsMR Headset))") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"(^(Spatial Controller))|(^(OpenVR Controller\(WindowsMR))") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"(^(Hand -))") ); #endif // Built-in layouts replaced by the com.unity.xr.oculus package. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OCULUS InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("^(Oculus Rift)|^(Oculus Quest)|^(Oculus Go)")); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"(^(Oculus Touch Controller))|(^(Oculus Quest Controller))")); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"Oculus Remote")); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"((Tracking Reference)|(^(Oculus Rift [a-zA-Z0-9]* \(Camera)))")); InputSystem.RegisterLayout( name: "GearVR", matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("Oculus HMD")); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("^(Oculus Tracked Remote)")); #endif // Built-in layouts replaced by the com.unity.xr.googlevr package. #if !DISABLE_BUILTIN_INPUT_SYSTEM_GOOGLEVR InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("Daydream HMD")); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("^(Daydream Controller)")); #endif // Built-in layouts replaced by the com.unity.xr.openvr package. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OPENVR InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("^(OpenVR Headset)|^(Vive Pro)") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct("^(OpenVR Controller\\(WindowsMR)") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithManufacturer("HTC") .WithProduct(@"^(OpenVR Controller\(((Vive. Controller)|(VIVE. Controller)|(Vive Controller)))") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(@"^(OpenVR Controller\(Oculus)") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithManufacturer("HTC") .WithProduct(@"^(VIVE Tracker)") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithManufacturer("HTC") .WithProduct(@"^(OpenVR Controller\(VIVE Tracker)") ); InputSystem.RegisterLayout( matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithManufacturer("HTC") .WithProduct(@"^(HTC V2-XD/XE)") ); #endif #endif } } } #endif