// 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; set; }
[InputControl(offset = 4, displayName = "Position")]
public Vector3Control position { get; set; }
[InputControl(offset = 16, displayName = "Rotation")]
public QuaternionControl rotation { get; 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; set; }
[InputControl(offset = 12, displayName = "LeftEyeRotation")]
public QuaternionControl leftEyeRotation { get; set; }
[InputControl(offset = 28, displayName = "RightEyePosition")]
public Vector3Control rightEyePosition { get; set; }
[InputControl(offset = 40, displayName = "RightEyeRotation")]
public QuaternionControl rightEyeRotation { get; set; }
[InputControl(offset = 56, displayName = "FixationPoint")]
public Vector3Control fixationPoint { get; set; }
[InputControl(offset = 68, displayName = "LeftEyeOpenAmount")]
public AxisControl leftEyeOpenAmount { get; set; }
[InputControl(offset = 72, displayName = "RightEyeOpenAmount")]
public AxisControl rightEyeOpenAmount { get; 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