first commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25ea971cc17caa84a8a2fdf9917af7b4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,273 @@
|
||||
// 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) && !UNITY_FORCE_INPUTSYSTEM_XR_OFF || PACKAGE_DOCS_GENERATION
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
using UnityEngine.Scripting;
|
||||
using TrackingState = UnityEngine.XR.InputTrackingState;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR
|
||||
{
|
||||
/// <summary>
|
||||
/// State layout for a single pose.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the low-level memory representation of a single pose, i.e the
|
||||
/// way poses are internally transmitted and stored in the system. PoseStates are used on devices containing <see cref="PoseControl"/>s.
|
||||
/// </remarks>
|
||||
/// <seealso cref="PoseControl"/>
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)]
|
||||
public struct PoseState : IInputStateTypeInfo
|
||||
{
|
||||
internal const int kSizeInBytes = 60;
|
||||
|
||||
internal static readonly FourCC s_Format = new FourCC('P', 'o', 's', 'e');
|
||||
|
||||
/// <summary>
|
||||
/// Memory format tag for PoseState.
|
||||
/// </summary>
|
||||
/// <value>Returns "Pose".</value>
|
||||
/// <seealso cref="InputStateBlock.format"/>
|
||||
public FourCC format => s_Format;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for PoseStates.
|
||||
///
|
||||
/// Useful for creating PoseStates locally (not from <see cref="PoseControl"/>).
|
||||
/// </summary>
|
||||
/// <param name="isTracked">Value to use for <see cref="isTracked"/></param>
|
||||
/// <param name="trackingState">Value to use for <see cref="trackingState"/></param>
|
||||
/// <param name="position">Value to use for <see cref="position"/></param>
|
||||
/// <param name="rotation">Value to use for <see cref="rotation"/></param>
|
||||
/// <param name="velocity">Value to use for <see cref="velocity"/></param>
|
||||
/// <param name="angularVelocity">Value to use for <see cref="angularVelocity"/></param>
|
||||
public PoseState(bool isTracked, TrackingState trackingState, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 angularVelocity)
|
||||
{
|
||||
this.isTracked = isTracked;
|
||||
this.trackingState = trackingState;
|
||||
this.position = position;
|
||||
this.rotation = rotation;
|
||||
this.velocity = velocity;
|
||||
this.angularVelocity = angularVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the pose is currently being fully tracked. Otherwise, the tracking is either unavailable, or simulated.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Fully tracked means that the pose is accurate and not using any simulated or extrapolated positions, and the system tracking this pose is able to confidently track this object.
|
||||
/// </remarks>
|
||||
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 8 /* needed to ensure optimization kicks-in */)]
|
||||
public bool isTracked;
|
||||
|
||||
/// <summary>
|
||||
/// A Flags Enumeration specifying which other fields in the pose state are valid.
|
||||
/// </summary>
|
||||
[FieldOffset(4), InputControl(displayName = "Tracking State", layout = "Integer")]
|
||||
public TrackingState trackingState;
|
||||
|
||||
/// <summary>
|
||||
/// The position in 3D space, relative to the tracking origin where this pose represents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Positions are represented in meters.
|
||||
/// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Position"/> value.
|
||||
/// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
|
||||
/// </remarks>
|
||||
[FieldOffset(8), InputControl(displayName = "Position", noisy = true)]
|
||||
public Vector3 position;
|
||||
|
||||
/// <summary>
|
||||
/// The rotation in 3D space, relative to the tracking origin where this pose represents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value.
|
||||
/// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
|
||||
/// </remarks>
|
||||
[FieldOffset(20), InputControl(displayName = "Rotation", noisy = true)]
|
||||
public Quaternion rotation;
|
||||
|
||||
/// <summary>
|
||||
/// The velocity in 3D space, relative to the tracking origin where this pose represents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Velocities are represented in meters per second.
|
||||
/// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value.
|
||||
/// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
|
||||
/// </remarks>
|
||||
[FieldOffset(36), InputControl(displayName = "Velocity", noisy = true)]
|
||||
public Vector3 velocity;
|
||||
|
||||
/// <summary>
|
||||
/// The angular velocity in 3D space, relative to the tracking origin where this pose represents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This field is only valid if <see cref="trackingState"/> contains the <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value.
|
||||
/// See <seealso cref="UnityEngine.XR.TrackingOriginModeFlags"/> for information on tracking origins.
|
||||
/// </remarks>
|
||||
[FieldOffset(48), InputControl(displayName = "Angular Velocity", noisy = true)]
|
||||
public Vector3 angularVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A control representing a Pose in 3D space, relative to an XR tracking origin
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that unlike most other control types, <c>PoseControls</c> do not have
|
||||
/// a flexible memory layout. They are hardwired to <see cref="PoseState"/> and
|
||||
/// will not work correctly with a different memory layouts. Additional fields may
|
||||
/// be appended to the struct but what's there in the struct has to be located
|
||||
/// at exactly those memory addresses.
|
||||
///
|
||||
/// For more information on tracking origins see <see cref="UnityEngine.XR.TrackingOriginModeFlags"/>.
|
||||
/// </remarks>
|
||||
[Preserve, InputControlLayout(stateType = typeof(PoseState))]
|
||||
public class PoseControl : InputControl<PoseState>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents whether this pose is fully tracked or unavailable/simulated.
|
||||
/// </summary>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.isTracked"/> value.</value>
|
||||
/// <seealso cref="PoseState.isTracked"/>
|
||||
public ButtonControl isTracked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The other controls on this <see cref="PoseControl"/> that are currently reporting data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be missing values when the device tracking this pose is restricted or not tracking properly.
|
||||
/// </remarks>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.trackingState"/> value of the pose retrieved from this control.</value>
|
||||
/// <seealso cref="PoseState.trackingState"/>
|
||||
public IntegerControl trackingState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The position, in meters, of this tracked pose relative to the tracking origin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Position"/> value.
|
||||
/// </remarks>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.position"/> value of the pose retrieved from this control.</value>
|
||||
/// <seealso cref="PoseState.position"/>
|
||||
public Vector3Control position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The rotation of this tracked pose relative to the tracking origin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Rotation"/> value.
|
||||
/// </remarks>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.rotation"/> value of the pose retrieved from this control.</value>
|
||||
/// <seealso cref="PoseState.rotation"/>
|
||||
public QuaternionControl rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The velocity, in meters per second, of this tracked pose relative to the tracking origin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.Velocity"/> value.
|
||||
/// </remarks>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.velocity"/> value of the pose retrieved from this control.</value>
|
||||
/// <seealso cref="PoseState.velocity"/>
|
||||
public Vector3Control velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The angular velocity of this tracked pose relative to the tracking origin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data for this control is only valid if the value returned from <see cref="trackingState"/> contains <see cref="UnityEngine.XR.InputTrackingState.AngularVelocity"/> value.
|
||||
/// </remarks>
|
||||
/// <value>Control representing whether the pose is being fully tracked. Maps to the <see cref="PoseState.angularVelocity"/> value of the pose retrieved from this control.</value>
|
||||
/// <seealso cref="PoseState.angularVelocity"/>
|
||||
public Vector3Control angularVelocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default-initialize the pose control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sets the <see cref="InputStateBlock.format"/> to <c>"Pose"</c>.
|
||||
/// </remarks>
|
||||
public PoseControl()
|
||||
{
|
||||
m_StateBlock.format = PoseState.s_Format;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
position = GetChildControl<Vector3Control>("position");
|
||||
rotation = GetChildControl<QuaternionControl>("rotation");
|
||||
velocity = GetChildControl<Vector3Control>("velocity");
|
||||
angularVelocity = GetChildControl<Vector3Control>("angularVelocity");
|
||||
|
||||
base.FinishSetup();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override unsafe PoseState ReadUnprocessedValueFromState(void* statePtr)
|
||||
{
|
||||
switch (m_OptimizedControlDataType)
|
||||
{
|
||||
case InputStateBlock.kFormatPose:
|
||||
return *(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset);
|
||||
default:
|
||||
return new PoseState()
|
||||
{
|
||||
isTracked = isTracked.ReadUnprocessedValueFromStateWithCaching(statePtr) > 0.5f,
|
||||
trackingState = (TrackingState)trackingState.ReadUnprocessedValueFromStateWithCaching(statePtr),
|
||||
position = position.ReadUnprocessedValueFromStateWithCaching(statePtr),
|
||||
rotation = rotation.ReadUnprocessedValueFromStateWithCaching(statePtr),
|
||||
velocity = velocity.ReadUnprocessedValueFromStateWithCaching(statePtr),
|
||||
angularVelocity = angularVelocity.ReadUnprocessedValueFromStateWithCaching(statePtr),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override unsafe void WriteValueIntoState(PoseState value, void* statePtr)
|
||||
{
|
||||
switch (m_OptimizedControlDataType)
|
||||
{
|
||||
case InputStateBlock.kFormatPose:
|
||||
*(PoseState*)((byte*)statePtr + (int)m_StateBlock.byteOffset) = value;
|
||||
break;
|
||||
default:
|
||||
isTracked.WriteValueIntoState(value.isTracked, statePtr);
|
||||
trackingState.WriteValueIntoState((uint)value.trackingState, statePtr);
|
||||
position.WriteValueIntoState(value.position, statePtr);
|
||||
rotation.WriteValueIntoState(value.rotation, statePtr);
|
||||
velocity.WriteValueIntoState(value.velocity, statePtr);
|
||||
angularVelocity.WriteValueIntoState(value.angularVelocity, statePtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override FourCC CalculateOptimizedControlDataType()
|
||||
{
|
||||
if (
|
||||
m_StateBlock.sizeInBits == PoseState.kSizeInBytes * 8 &&
|
||||
m_StateBlock.bitOffset == 0 &&
|
||||
isTracked.optimizedControlDataType == InputStateBlock.kFormatByte &&
|
||||
trackingState.optimizedControlDataType == InputStateBlock.kFormatInt &&
|
||||
position.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
|
||||
rotation.optimizedControlDataType == InputStateBlock.kFormatQuaternion &&
|
||||
velocity.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
|
||||
angularVelocity.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
|
||||
trackingState.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 4 &&
|
||||
position.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 8 &&
|
||||
rotation.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 20 &&
|
||||
velocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 36 &&
|
||||
angularVelocity.m_StateBlock.byteOffset == isTracked.m_StateBlock.byteOffset + 48
|
||||
)
|
||||
return InputStateBlock.kFormatPose;
|
||||
|
||||
return InputStateBlock.kFormatInvalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31038076760c2c744a116e944e0e18d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ada2e545c685b44a8367bdab267f0dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
// Docs generation is skipped because these are intended to be replaced with the com.unity.xr.googlevr package.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) && !DISABLE_BUILTIN_INPUT_SYSTEM_GOOGLEVR && !UNITY_FORCE_INPUTSYSTEM_XR_OFF && !PACKAGE_DOCS_GENERATION
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
namespace Unity.XR.GoogleVr
|
||||
{
|
||||
/// <summary>
|
||||
/// A head-mounted display powered by Google Daydream.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Daydream Headset", hideInUI = true)]
|
||||
public class DaydreamHMD : XRHMD
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An XR controller powered by Google Daydream.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Daydream Controller", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class DaydreamController : XRController
|
||||
{
|
||||
[InputControl]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl volumeUp { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl recentered { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl volumeDown { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl recentering { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl app { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl home { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl touchpadClicked { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl touchpadTouched { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAcceleration { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
touchpad = GetChildControl<Vector2Control>("touchpad");
|
||||
volumeUp = GetChildControl<ButtonControl>("volumeUp");
|
||||
recentered = GetChildControl<ButtonControl>("recentered");
|
||||
volumeDown = GetChildControl<ButtonControl>("volumeDown");
|
||||
recentering = GetChildControl<ButtonControl>("recentering");
|
||||
app = GetChildControl<ButtonControl>("app");
|
||||
home = GetChildControl<ButtonControl>("home");
|
||||
touchpadClicked = GetChildControl<ButtonControl>("touchpadClicked");
|
||||
touchpadTouched = GetChildControl<ButtonControl>("touchpadTouched");
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAcceleration = GetChildControl<Vector3Control>("deviceAcceleration");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44353112a58c73347adde914844b7642
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,241 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
// Docs generation is skipped because these are intended to be replaced with the com.unity.xr.oculus package.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) && !DISABLE_BUILTIN_INPUT_SYSTEM_OCULUS && !UNITY_FORCE_INPUTSYSTEM_XR_OFF && !PACKAGE_DOCS_GENERATION
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
namespace Unity.XR.Oculus.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// An Oculus VR headset (such as the Oculus Rift series of devices).
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Oculus Headset", hideInUI = true)]
|
||||
public class OculusHMD : XRHMD
|
||||
{
|
||||
[InputControl]
|
||||
[InputControl(name = "trackingState", layout = "Integer", aliases = new[] { "devicetrackingstate" })]
|
||||
[InputControl(name = "isTracked", layout = "Button", aliases = new[] { "deviceistracked" })]
|
||||
public ButtonControl userPresence { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyeAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyeAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyeAngularAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyeAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyeAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyeAngularAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyeAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyeAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyeAngularAcceleration { get; protected set; }
|
||||
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
userPresence = GetChildControl<ButtonControl>("userPresence");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
deviceAcceleration = GetChildControl<Vector3Control>("deviceAcceleration");
|
||||
deviceAngularAcceleration = GetChildControl<Vector3Control>("deviceAngularAcceleration");
|
||||
leftEyeAngularVelocity = GetChildControl<Vector3Control>("leftEyeAngularVelocity");
|
||||
leftEyeAcceleration = GetChildControl<Vector3Control>("leftEyeAcceleration");
|
||||
leftEyeAngularAcceleration = GetChildControl<Vector3Control>("leftEyeAngularAcceleration");
|
||||
rightEyeAngularVelocity = GetChildControl<Vector3Control>("rightEyeAngularVelocity");
|
||||
rightEyeAcceleration = GetChildControl<Vector3Control>("rightEyeAcceleration");
|
||||
rightEyeAngularAcceleration = GetChildControl<Vector3Control>("rightEyeAngularAcceleration");
|
||||
centerEyeAngularVelocity = GetChildControl<Vector3Control>("centerEyeAngularVelocity");
|
||||
centerEyeAcceleration = GetChildControl<Vector3Control>("centerEyeAcceleration");
|
||||
centerEyeAngularAcceleration = GetChildControl<Vector3Control>("centerEyeAngularAcceleration");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Oculus Touch controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Oculus Touch Controller", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class OculusTouchController : XRControllerWithRumble
|
||||
{
|
||||
[InputControl(aliases = new[] { "Primary2DAxis", "Joystick" })]
|
||||
public Vector2Control thumbstick { get; protected set; }
|
||||
|
||||
[InputControl]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl]
|
||||
public AxisControl grip { get; protected set; }
|
||||
|
||||
[InputControl(aliases = new[] { "A", "X", "Alternate" })]
|
||||
public ButtonControl primaryButton { get; protected set; }
|
||||
[InputControl(aliases = new[] { "B", "Y", "Primary" })]
|
||||
public ButtonControl secondaryButton { get; protected set; }
|
||||
[InputControl(aliases = new[] { "GripButton" })]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl start { get; protected set; }
|
||||
[InputControl(aliases = new[] { "JoystickOrPadPressed", "thumbstickClick" })]
|
||||
public ButtonControl thumbstickClicked { get; protected set; }
|
||||
[InputControl(aliases = new[] { "ATouched", "XTouched", "ATouch", "XTouch" })]
|
||||
public ButtonControl primaryTouched { get; protected set; }
|
||||
[InputControl(aliases = new[] { "BTouched", "YTouched", "BTouch", "YTouch" })]
|
||||
public ButtonControl secondaryTouched { get; protected set; }
|
||||
[InputControl(aliases = new[] { "indexTouch", "indexNearTouched" })]
|
||||
public AxisControl triggerTouched { get; protected set; }
|
||||
[InputControl(aliases = new[] { "indexButton", "indexTouched" })]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "JoystickOrPadTouched", "thumbstickTouch" })]
|
||||
[InputControl(name = "trackingState", layout = "Integer", aliases = new[] { "controllerTrackingState" })]
|
||||
[InputControl(name = "isTracked", layout = "Button", aliases = new[] { "ControllerIsTracked" })]
|
||||
[InputControl(name = "devicePosition", layout = "Vector3", aliases = new[] { "controllerPosition" })]
|
||||
[InputControl(name = "deviceRotation", layout = "Quaternion", aliases = new[] { "controllerRotation" })]
|
||||
public ButtonControl thumbstickTouched { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "controllerVelocity" })]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "controllerAngularVelocity" })]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "controllerAcceleration" })]
|
||||
public Vector3Control deviceAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "controllerAngularAcceleration" })]
|
||||
public Vector3Control deviceAngularAcceleration { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
thumbstick = GetChildControl<Vector2Control>("thumbstick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerTouched = GetChildControl<AxisControl>("triggerTouched");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
start = GetChildControl<ButtonControl>("start");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
primaryTouched = GetChildControl<ButtonControl>("primaryTouched");
|
||||
secondaryTouched = GetChildControl<ButtonControl>("secondaryTouched");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
deviceAcceleration = GetChildControl<Vector3Control>("deviceAcceleration");
|
||||
deviceAngularAcceleration = GetChildControl<Vector3Control>("deviceAngularAcceleration");
|
||||
}
|
||||
}
|
||||
|
||||
public class OculusTrackingReference : TrackedDevice
|
||||
{
|
||||
[InputControl(aliases = new[] { "trackingReferenceTrackingState" })]
|
||||
public new IntegerControl trackingState { get; protected set; }
|
||||
[InputControl(aliases = new[] { "trackingReferenceIsTracked" })]
|
||||
public new ButtonControl isTracked { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
trackingState = GetChildControl<IntegerControl>("trackingState");
|
||||
isTracked = GetChildControl<ButtonControl>("isTracked");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Oculus Remote controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Oculus Remote", hideInUI = true)]
|
||||
public class OculusRemote : InputDevice
|
||||
{
|
||||
[InputControl]
|
||||
public ButtonControl back { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl start { get; protected set; }
|
||||
[InputControl]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
back = GetChildControl<ButtonControl>("back");
|
||||
start = GetChildControl<ButtonControl>("start");
|
||||
touchpad = GetChildControl<Vector2Control>("touchpad");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Standalone VR headset that includes on-headset controls.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Oculus Headset (w/ on-headset controls)", hideInUI = true)]
|
||||
public class OculusHMDExtended : OculusHMD
|
||||
{
|
||||
[InputControl]
|
||||
public ButtonControl back { get; protected set; }
|
||||
[InputControl]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
back = GetChildControl<ButtonControl>("back");
|
||||
touchpad = GetChildControl<Vector2Control>("touchpad");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Gear VR controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "GearVR Controller", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class GearVRTrackedController : XRController
|
||||
{
|
||||
[InputControl]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
[InputControl]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl back { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl touchpadClicked { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl touchpadTouched { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAcceleration { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularAcceleration { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
touchpad = GetChildControl<Vector2Control>("touchpad");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
back = GetChildControl<ButtonControl>("back");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
touchpadClicked = GetChildControl<ButtonControl>("touchpadClicked");
|
||||
touchpadTouched = GetChildControl<ButtonControl>("touchpadTouched");
|
||||
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
deviceAcceleration = GetChildControl<Vector3Control>("deviceAcceleration");
|
||||
deviceAngularAcceleration = GetChildControl<Vector3Control>("deviceAngularAcceleration");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 150936adb4fc13049a1001992b86c43e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,251 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
// Docs generation is skipped because these are intended to be replaced with the com.unity.xr.openvr package.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) && !DISABLE_BUILTIN_INPUT_SYSTEM_OPENVR && !UNITY_FORCE_INPUTSYSTEM_XR_OFF && !PACKAGE_DOCS_GENERATION
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
namespace Unity.XR.OpenVR
|
||||
{
|
||||
[InputControlLayout(displayName = "OpenVR Headset", hideInUI = true)]
|
||||
public class OpenVRHMD : XRHMD
|
||||
{
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyeVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyeAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyeVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyeAngularVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyeVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyeAngularVelocity { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
leftEyeVelocity = GetChildControl<Vector3Control>("leftEyeVelocity");
|
||||
leftEyeAngularVelocity = GetChildControl<Vector3Control>("leftEyeAngularVelocity");
|
||||
rightEyeVelocity = GetChildControl<Vector3Control>("rightEyeVelocity");
|
||||
rightEyeAngularVelocity = GetChildControl<Vector3Control>("rightEyeAngularVelocity");
|
||||
centerEyeVelocity = GetChildControl<Vector3Control>("centerEyeVelocity");
|
||||
centerEyeAngularVelocity = GetChildControl<Vector3Control>("centerEyeAngularVelocity");
|
||||
}
|
||||
}
|
||||
|
||||
[InputControlLayout(displayName = "Windows MR Controller (OpenVR)", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class OpenVRControllerWMR : XRController
|
||||
{
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
|
||||
[InputControl(aliases = new[] { "primary2DAxisClick", "joystickOrPadPressed" })]
|
||||
public ButtonControl touchpadClick { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxisTouch", "joystickOrPadTouched" })]
|
||||
public ButtonControl touchpadTouch { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary" })]
|
||||
public ButtonControl menu { get; protected set; }
|
||||
|
||||
[InputControl]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl]
|
||||
public AxisControl grip { get; protected set; }
|
||||
|
||||
[InputControl(aliases = new[] { "secondary2DAxis" })]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxis" })]
|
||||
public Vector2Control joystick { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
|
||||
touchpadClick = GetChildControl<ButtonControl>("touchpadClick");
|
||||
touchpadTouch = GetChildControl<ButtonControl>("touchpadTouch");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
menu = GetChildControl<ButtonControl>("menu");
|
||||
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
|
||||
touchpad = GetChildControl<Vector2Control>("touchpad");
|
||||
joystick = GetChildControl<Vector2Control>("joystick");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An HTC Vive Wand controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Vive Wand", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class ViveWand : XRControllerWithRumble
|
||||
{
|
||||
[InputControl]
|
||||
public AxisControl grip { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl primary { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxisClick", "joystickOrPadPressed" })]
|
||||
public ButtonControl trackpadPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxisTouch", "joystickOrPadTouched" })]
|
||||
public ButtonControl trackpadTouched { get; protected set; }
|
||||
[InputControl(aliases = new[] { "Primary2DAxis" })]
|
||||
public Vector2Control trackpad { get; protected set; }
|
||||
[InputControl]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
primary = GetChildControl<ButtonControl>("primary");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
trackpadPressed = GetChildControl<ButtonControl>("trackpadPressed");
|
||||
trackpadTouched = GetChildControl<ButtonControl>("trackpadTouched");
|
||||
trackpad = GetChildControl<Vector2Control>("trackpad");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An HTC Vive lighthouse.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Vive Lighthouse", hideInUI = true)]
|
||||
public class ViveLighthouse : TrackedDevice
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An HTC Vive tracker.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Vive Tracker")]
|
||||
public class ViveTracker : TrackedDevice
|
||||
{
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
}
|
||||
}
|
||||
|
||||
[InputControlLayout(displayName = "Handed Vive Tracker", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class HandedViveTracker : ViveTracker
|
||||
{
|
||||
[InputControl]
|
||||
public AxisControl grip { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl primary { get; protected set; }
|
||||
[InputControl(aliases = new[] { "JoystickOrPadPressed" })]
|
||||
public ButtonControl trackpadPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
primary = GetChildControl<ButtonControl>("primary");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
trackpadPressed = GetChildControl<ButtonControl>("trackpadPressed");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
|
||||
base.FinishSetup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Oculus Touch controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Oculus Touch Controller (OpenVR)", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class OpenVROculusTouchController : XRControllerWithRumble
|
||||
{
|
||||
[InputControl]
|
||||
public Vector2Control thumbstick { get; protected set; }
|
||||
|
||||
[InputControl]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl]
|
||||
public AxisControl grip { get; protected set; }
|
||||
|
||||
// Primary & Secondary are switched in order to retain consistency with the Oculus SDK
|
||||
[InputControl(aliases = new[] { "Alternate" })]
|
||||
public ButtonControl primaryButton { get; protected set; }
|
||||
[InputControl(aliases = new[] { "Primary" })]
|
||||
public ButtonControl secondaryButton { get; protected set; }
|
||||
|
||||
[InputControl]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxisClicked" })]
|
||||
public ButtonControl thumbstickClicked { get; protected set; }
|
||||
[InputControl(aliases = new[] { "primary2DAxisTouch" })]
|
||||
public ButtonControl thumbstickTouched { get; protected set; }
|
||||
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
thumbstick = GetChildControl<Vector2Control>("thumbstick");
|
||||
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
grip = GetChildControl<AxisControl>("grip");
|
||||
|
||||
primaryButton = GetChildControl<ButtonControl>("primaryButton");
|
||||
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
|
||||
gripPressed = GetChildControl<ButtonControl>("gripPressed");
|
||||
thumbstickClicked = GetChildControl<ButtonControl>("thumbstickClicked");
|
||||
thumbstickTouched = GetChildControl<ButtonControl>("thumbstickTouched");
|
||||
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
|
||||
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a2cdc9fdde66bb49afa0763a7557ff9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,118 @@
|
||||
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
|
||||
// Docs generation is skipped because these are intended to be replaced with the com.unity.xr.windowsmr package.
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) && !DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR && !UNITY_FORCE_INPUTSYSTEM_XR_OFF && !PACKAGE_DOCS_GENERATION
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
namespace UnityEngine.XR.WindowsMR.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// A Windows Mixed Reality XR headset.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "Windows MR Headset", hideInUI = true)]
|
||||
public class WMRHMD : XRHMD
|
||||
{
|
||||
[InputControl]
|
||||
[InputControl(name = "devicePosition", layout = "Vector3", aliases = new[] { "HeadPosition" })]
|
||||
[InputControl(name = "deviceRotation", layout = "Quaternion", aliases = new[] { "HeadRotation" })]
|
||||
public ButtonControl userPresence { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
userPresence = GetChildControl<ButtonControl>("userPresence");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Windows Mixed Reality XR controller.
|
||||
/// </summary>
|
||||
[InputControlLayout(displayName = "HoloLens Hand", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class HololensHand : XRController
|
||||
{
|
||||
[InputControl(noisy = true, aliases = new[] { "gripVelocity" })]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(aliases = new[] { "triggerbutton" })]
|
||||
public ButtonControl airTap { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public AxisControl sourceLossRisk { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control sourceLossMitigationDirection { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
airTap = GetChildControl<ButtonControl>("airTap");
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
sourceLossRisk = GetChildControl<AxisControl>("sourceLossRisk");
|
||||
sourceLossMitigationDirection = GetChildControl<Vector3Control>("sourceLossMitigationDirection");
|
||||
}
|
||||
}
|
||||
|
||||
[InputControlLayout(displayName = "Windows MR Controller", commonUsages = new[] { "LeftHand", "RightHand" }, hideInUI = true)]
|
||||
public class WMRSpatialController : XRControllerWithRumble
|
||||
{
|
||||
[InputControl(aliases = new[] { "Primary2DAxis", "thumbstickaxes" })]
|
||||
public Vector2Control joystick { get; protected set; }
|
||||
[InputControl(aliases = new[] { "Secondary2DAxis", "touchpadaxes" })]
|
||||
public Vector2Control touchpad { get; protected set; }
|
||||
[InputControl(aliases = new[] { "gripaxis" })]
|
||||
public AxisControl grip { get; protected set; }
|
||||
[InputControl(aliases = new[] { "gripbutton" })]
|
||||
public ButtonControl gripPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "Primary", "menubutton" })]
|
||||
public ButtonControl menu { get; protected set; }
|
||||
[InputControl(aliases = new[] { "triggeraxis" })]
|
||||
public AxisControl trigger { get; protected set; }
|
||||
[InputControl(aliases = new[] { "triggerbutton" })]
|
||||
public ButtonControl triggerPressed { get; protected set; }
|
||||
[InputControl(aliases = new[] { "thumbstickpressed" })]
|
||||
public ButtonControl joystickClicked { get; protected set; }
|
||||
[InputControl(aliases = new[] { "joystickorpadpressed", "touchpadpressed" })]
|
||||
public ButtonControl touchpadClicked { get; protected set; }
|
||||
[InputControl(aliases = new[] { "joystickorpadtouched", "touchpadtouched" })]
|
||||
public ButtonControl touchpadTouched { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "gripVelocity" })]
|
||||
public Vector3Control deviceVelocity { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "gripAngularVelocity" })]
|
||||
public Vector3Control deviceAngularVelocity { get; protected set; }
|
||||
|
||||
[InputControl(noisy = true)]
|
||||
public AxisControl batteryLevel { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public AxisControl sourceLossRisk { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control sourceLossMitigationDirection { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control pointerPosition { get; protected set; }
|
||||
[InputControl(noisy = true, aliases = new[] { "PointerOrientation" })]
|
||||
public QuaternionControl pointerRotation { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
joystick = GetChildControl<Vector2Control>("joystick");
|
||||
trigger = GetChildControl<AxisControl>("trigger");
|
||||
touchpad = GetChildControl<Vector2Control>("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");
|
||||
deviceVelocity = GetChildControl<Vector3Control>("deviceVelocity");
|
||||
deviceAngularVelocity = GetChildControl<Vector3Control>("deviceAngularVelocity");
|
||||
|
||||
batteryLevel = GetChildControl<AxisControl>("batteryLevel");
|
||||
sourceLossRisk = GetChildControl<AxisControl>("sourceLossRisk");
|
||||
sourceLossMitigationDirection = GetChildControl<Vector3Control>("sourceLossMitigationDirection");
|
||||
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
|
||||
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9231fc068a549684f8ece75b66d6095b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,129 @@
|
||||
// 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) && !UNITY_FORCE_INPUTSYSTEM_XR_OFF || PACKAGE_DOCS_GENERATION
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.XR.Haptics;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR
|
||||
{
|
||||
[InputControlLayout(isGenericTypeOfDevice = true, displayName = "XR HMD", canRunInBackground = true)]
|
||||
public class XRHMD : TrackedDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// The base type of all XR head mounted displays. This can help organize shared behaviour across all HMDs.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
///
|
||||
/// To give your head tracking an extra update before rendering:
|
||||
/// First, enable before render updates on your Device.
|
||||
///
|
||||
/// <sample>
|
||||
/// <code>
|
||||
/// // JSON
|
||||
/// {
|
||||
/// "name" : "MyHMD",
|
||||
/// "extend" : "HMD",
|
||||
/// "beforeRender" : "Update"
|
||||
/// }
|
||||
/// </code>
|
||||
/// </sample>
|
||||
///
|
||||
/// Then, make sure you put extra `StateEvents` for your HMD on the queue right in time before rendering. Also, if your HMD is a combination of non-tracking and tracking controls, you can update just the tracking by sending a delta event instead of a full state event.
|
||||
///
|
||||
/// </remarks>
|
||||
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control leftEyePosition { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public QuaternionControl leftEyeRotation { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control rightEyePosition { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public QuaternionControl rightEyeRotation { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public Vector3Control centerEyePosition { get; protected set; }
|
||||
[InputControl(noisy = true)]
|
||||
public QuaternionControl centerEyeRotation { get; protected set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
centerEyePosition = GetChildControl<Vector3Control>("centerEyePosition");
|
||||
centerEyeRotation = GetChildControl<QuaternionControl>("centerEyeRotation");
|
||||
leftEyePosition = GetChildControl<Vector3Control>("leftEyePosition");
|
||||
leftEyeRotation = GetChildControl<QuaternionControl>("leftEyeRotation");
|
||||
rightEyePosition = GetChildControl<Vector3Control>("rightEyePosition");
|
||||
rightEyeRotation = GetChildControl<QuaternionControl>("rightEyeRotation");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The base type for all XR handed controllers.
|
||||
/// </summary>
|
||||
[InputControlLayout(commonUsages = new[] { "LeftHand", "RightHand" }, isGenericTypeOfDevice = true, displayName = "XR Controller")]
|
||||
public class XRController : TrackedDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// A quick accessor for the currently active left handed device.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If there is no left hand connected, this will be null.
|
||||
/// This also matches any currently tracked device that contains the 'LeftHand' device usage.
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // To set up an Action to specifically target
|
||||
/// // the left-hand XR controller:
|
||||
///
|
||||
/// var action = new InputAction(binding: "/<XRController>{leftHand}/position");
|
||||
/// </code>
|
||||
/// </example>
|
||||
///
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // To make the left-hand XR controller behave like the right-hand one
|
||||
/// var controller = XRController.leftHand;
|
||||
/// InputSystem.SetUsage(controller, CommonUsages.RightHand);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public static XRController leftHand => InputSystem.GetDevice<XRController>(CommonUsages.LeftHand);
|
||||
|
||||
/// <summary>
|
||||
/// A quick accessor for the currently active right handed device. This is also tracked via usages on the device.
|
||||
/// </summary>
|
||||
/// <remarks>If there is no left hand connected, this will be null. This also matches any currently tracked device that contains the 'RightHand' device usage.</remarks>
|
||||
public static XRController rightHand => InputSystem.GetDevice<XRController>(CommonUsages.RightHand);
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
|
||||
var capabilities = description.capabilities;
|
||||
var deviceDescriptor = XRDeviceDescriptor.FromJson(capabilities);
|
||||
|
||||
if (deviceDescriptor != null)
|
||||
{
|
||||
if ((deviceDescriptor.characteristics & InputDeviceCharacteristics.Left) != 0)
|
||||
InputSystem.SetDeviceUsage(this, CommonUsages.LeftHand);
|
||||
else if ((deviceDescriptor.characteristics & InputDeviceCharacteristics.Right) != 0)
|
||||
InputSystem.SetDeviceUsage(this, CommonUsages.RightHand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies a controller that is capable of rumble or haptics.
|
||||
/// </summary>
|
||||
public class XRControllerWithRumble : XRController
|
||||
{
|
||||
public void SendImpulse(float amplitude, float duration)
|
||||
{
|
||||
var command = SendHapticImpulseCommand.Create(0, amplitude, duration);
|
||||
ExecuteCommand(ref command);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 929bef69d71fe4223b4148865a0a5e42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8529451a1ee99484a891bdea2f5219f3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
public struct BufferedRumble
|
||||
{
|
||||
public HapticCapabilities capabilities { get; private set; }
|
||||
InputDevice device { get; set; }
|
||||
|
||||
public BufferedRumble(InputDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new System.ArgumentNullException(nameof(device));
|
||||
|
||||
this.device = device;
|
||||
|
||||
var command = GetHapticCapabilitiesCommand.Create();
|
||||
device.ExecuteCommand(ref command);
|
||||
capabilities = command.capabilities;
|
||||
}
|
||||
|
||||
public void EnqueueRumble(byte[] samples)
|
||||
{
|
||||
var command = SendBufferedHapticCommand.Create(samples);
|
||||
device.ExecuteCommand(ref command);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1e8cf3dc2c11ed47a2666fcf0d3a938
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
public struct HapticState
|
||||
{
|
||||
public HapticState(uint samplesQueued, uint samplesAvailable)
|
||||
{
|
||||
this.samplesQueued = samplesQueued;
|
||||
this.samplesAvailable = samplesAvailable;
|
||||
}
|
||||
|
||||
public uint samplesQueued { get; private set; }
|
||||
public uint samplesAvailable { get; private set; }
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct GetCurrentHapticStateCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'S', '0');
|
||||
|
||||
const int kSize = InputDeviceCommand.kBaseCommandSize + (sizeof(uint) * 2);
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
public uint samplesQueued;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
public uint samplesAvailable;
|
||||
|
||||
public HapticState currentState => new HapticState(samplesQueued, samplesAvailable);
|
||||
|
||||
public static GetCurrentHapticStateCommand Create()
|
||||
{
|
||||
return new GetCurrentHapticStateCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0049e966b9953774fa3d07808a5555a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the haptic capabilities of a specific device.
|
||||
/// </summary>
|
||||
public struct HapticCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes and returns an instance of <see cref="HapticCapabilities"/>.
|
||||
/// </summary>
|
||||
/// <param name="numChannels">The number of haptic channels available on this device.</param>
|
||||
/// <param name="supportsImpulse">This device supports sending a haptic impulse.</param>
|
||||
/// <param name="supportsBuffer">This device supports sending a haptic buffer.</param>
|
||||
/// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
|
||||
/// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
|
||||
/// <param name="optimalBufferSize">The optimal size of a device's buffer, taking into account frequency and latency.</param>
|
||||
public HapticCapabilities(uint numChannels, bool supportsImpulse, bool supportsBuffer, uint frequencyHz, uint maxBufferSize, uint optimalBufferSize)
|
||||
{
|
||||
this.numChannels = numChannels;
|
||||
this.supportsImpulse = supportsImpulse;
|
||||
this.supportsBuffer = supportsBuffer;
|
||||
this.frequencyHz = frequencyHz;
|
||||
this.maxBufferSize = maxBufferSize;
|
||||
this.optimalBufferSize = optimalBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated. Use <see cref="HapticCapabilities(uint, bool, bool, uint, uint, uint)"/> instead.
|
||||
/// This constructor did not match the native haptic capabilities struct and was missing properties.
|
||||
/// </summary>
|
||||
/// <param name="numChannels">The number of haptic channels available on this device.</param>
|
||||
/// <param name="frequencyHz">The buffer frequency the device operates at in Hertz.</param>
|
||||
/// <param name="maxBufferSize">The max amount of buffer data that can be stored by the device.</param>
|
||||
public HapticCapabilities(uint numChannels, uint frequencyHz, uint maxBufferSize)
|
||||
: this(numChannels, false, false, frequencyHz, maxBufferSize, 0U)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of haptic channels available on this device.
|
||||
/// </summary>
|
||||
public uint numChannels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic impulse.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendHapticImpulseCommand"/>
|
||||
public bool supportsImpulse { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic buffer.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendBufferedHapticCommand"/>
|
||||
public bool supportsBuffer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
|
||||
/// </remarks>
|
||||
public uint frequencyHz { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The max amount of buffer data that can be stored by the device.
|
||||
/// </summary>
|
||||
public uint maxBufferSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The optimal size of a device's buffer, taking into account frequency and latency.
|
||||
/// </summary>
|
||||
public uint optimalBufferSize { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input device command struct for retrieving the haptic capabilities of a device.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct GetHapticCapabilitiesCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'C', '0');
|
||||
|
||||
// 20 bytes of data from uint(4) + bool(1) + bool(1) + padding + uint(4) + uint(4) + uint(4)
|
||||
const int kSize = InputDeviceCommand.kBaseCommandSize + 20;
|
||||
|
||||
/// <inheritdoc />
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
/// <summary>
|
||||
/// The number of haptic channels available on this device.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
public uint numChannels;
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic impulse.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendHapticImpulseCommand"/>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 4)]
|
||||
public bool supportsImpulse;
|
||||
|
||||
/// <summary>
|
||||
/// This device supports sending a haptic buffer.
|
||||
/// </summary>
|
||||
/// <seealso cref="SendBufferedHapticCommand"/>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 5)]
|
||||
public bool supportsBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer frequency the device operates at in Hertz. This impacts how fast the device consumes buffered haptic data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value is greater than 0 if <see cref="supportsBuffer"/> is <see langword="true"/>, and 0 otherwise.
|
||||
/// </remarks>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 8)]
|
||||
public uint frequencyHz;
|
||||
|
||||
/// <summary>
|
||||
/// The max amount of buffer data that can be stored by the device.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 12)]
|
||||
public uint maxBufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The optimal size of a device's buffer, taking into account frequency and latency.
|
||||
/// </summary>
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + 16)]
|
||||
public uint optimalBufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The haptic capabilities of the device, populated after this command is executed.
|
||||
/// </summary>
|
||||
public HapticCapabilities capabilities => new HapticCapabilities(numChannels, supportsImpulse, supportsBuffer, frequencyHz, maxBufferSize, optimalBufferSize);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns a new initialized input device command struct for retrieving
|
||||
/// the haptic capabilities of a device when executed.
|
||||
/// </summary>
|
||||
/// <returns>Returns a new command struct with the data header initialized, making it ready to execute.</returns>
|
||||
/// <seealso cref="InputDevice.ExecuteCommand{TCommand}(ref TCommand)"/>
|
||||
public static GetHapticCapabilitiesCommand Create()
|
||||
{
|
||||
return new GetHapticCapabilitiesCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ade21199e79d394ab34f4e6887f1c09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public unsafe struct SendBufferedHapticCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'U', '0');
|
||||
|
||||
private const int kMaxHapticBufferSize = 1024;
|
||||
private const int kSize = InputDeviceCommand.kBaseCommandSize + (sizeof(int) * 2) + (kMaxHapticBufferSize * sizeof(byte));
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
private int channel;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
private int bufferSize;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + (sizeof(int) * 2))]
|
||||
private fixed byte buffer[kMaxHapticBufferSize];
|
||||
|
||||
public static SendBufferedHapticCommand Create(byte[] rumbleBuffer)
|
||||
{
|
||||
if (rumbleBuffer == null)
|
||||
throw new System.ArgumentNullException(nameof(rumbleBuffer));
|
||||
|
||||
var rumbleBufferSize = Mathf.Min(kMaxHapticBufferSize, rumbleBuffer.Length);
|
||||
var newCommand = new SendBufferedHapticCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
bufferSize = rumbleBufferSize
|
||||
};
|
||||
|
||||
//TODO TOMB: There must be a more effective, bulk copy operation for fixed buffers than this.
|
||||
//Replace if found.
|
||||
var commandPtr = &newCommand;
|
||||
fixed(byte* src = rumbleBuffer)
|
||||
{
|
||||
for (int cpyIndex = 0; cpyIndex < rumbleBufferSize; cpyIndex++)
|
||||
commandPtr->buffer[cpyIndex] = src[cpyIndex];
|
||||
}
|
||||
|
||||
return newCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e553fed0b97be3349aff36916eb6fefc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR.Haptics
|
||||
{
|
||||
/// <summary>
|
||||
/// A device command sent to a device to set it's motor rumble amplitude for a set duration.
|
||||
/// </summary>
|
||||
/// <remarks>This is directly used by the <see cref="XRControllerWithRumble"/> class. For clearer details of using this command, see that class.</remarks>
|
||||
[StructLayout(LayoutKind.Explicit, Size = kSize)]
|
||||
public struct SendHapticImpulseCommand : IInputDeviceCommandInfo
|
||||
{
|
||||
static FourCC Type => new FourCC('X', 'H', 'I', '0');
|
||||
|
||||
private const int kSize = InputDeviceCommand.kBaseCommandSize + sizeof(int) + (sizeof(float) * 2);
|
||||
|
||||
[FieldOffset(0)]
|
||||
InputDeviceCommand baseCommand;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize)]
|
||||
private int channel;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int))]
|
||||
private float amplitude;
|
||||
|
||||
[FieldOffset(InputDeviceCommand.kBaseCommandSize + sizeof(int) + (sizeof(float)))]
|
||||
private float duration;
|
||||
|
||||
public FourCC typeStatic => Type;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a device command that can then be sent to a specific device.
|
||||
/// </summary>
|
||||
/// <param name="motorChannel">The desired motor you want to rumble</param>
|
||||
/// <param name="motorAmplitude">The desired motor amplitude that should be within a [0-1] range.</param>
|
||||
/// <param name="motorDuration">The desired duration of the impulse in seconds.</param>
|
||||
/// <returns>The command that should be sent to the device via <c>InputDevice.ExecuteCommand</c>.</returns>
|
||||
public static SendHapticImpulseCommand Create(int motorChannel, float motorAmplitude, float motorDuration)
|
||||
{
|
||||
return new SendHapticImpulseCommand
|
||||
{
|
||||
baseCommand = new InputDeviceCommand(Type, kSize),
|
||||
channel = motorChannel,
|
||||
amplitude = motorAmplitude,
|
||||
duration = motorDuration
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f84d6a1bd34ea6428fa1db0e9f459cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,677 @@
|
||||
using System;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="TrackedPoseDriver"/> component applies the current pose value of a tracked device
|
||||
/// to the <see cref="Transform"/> of the <see cref="GameObject"/>.
|
||||
/// <see cref="TrackedPoseDriver"/> can track multiple types of devices including XR HMDs, controllers, and remotes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For <see cref="positionInput"/> and <see cref="rotationInput"/>, if an action is directly defined
|
||||
/// in the <see cref="InputActionProperty"/>, as opposed to a reference to an action externally defined
|
||||
/// in an <see cref="InputActionAsset"/>, the action will automatically be enabled and disabled by this
|
||||
/// behavior during <see cref="OnEnable"/> and <see cref="OnDisable"/>. The enabled state for actions
|
||||
/// externally defined must be managed externally from this behavior.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[AddComponentMenu("XR/Tracked Pose Driver (Input System)")]
|
||||
public class TrackedPoseDriver : MonoBehaviour, ISerializationCallbackReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for which <see cref="Transform"/> properties to update.
|
||||
/// </summary>
|
||||
/// <seealso cref="trackingType"/>
|
||||
public enum TrackingType
|
||||
{
|
||||
/// <summary>
|
||||
/// Update both rotation and position.
|
||||
/// </summary>
|
||||
RotationAndPosition,
|
||||
|
||||
/// <summary>
|
||||
/// Update rotation only.
|
||||
/// </summary>
|
||||
RotationOnly,
|
||||
|
||||
/// <summary>
|
||||
/// Update position only.
|
||||
/// </summary>
|
||||
PositionOnly,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// These bit flags correspond with <c>UnityEngine.XR.InputTrackingState</c>
|
||||
/// but that enum is not used to avoid adding a dependency to the XR module.
|
||||
/// Only the Position and Rotation flags are used by this class, so velocity and acceleration flags are not duplicated here.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
enum TrackingStates
|
||||
{
|
||||
/// <summary>
|
||||
/// Position and rotation are not valid.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Position is valid.
|
||||
/// See <c>InputTrackingState.Position</c>.
|
||||
/// </summary>
|
||||
Position = 1 << 0,
|
||||
|
||||
/// <summary>
|
||||
/// Rotation is valid.
|
||||
/// See <c>InputTrackingState.Rotation</c>.
|
||||
/// </summary>
|
||||
Rotation = 1 << 1,
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("Which Transform properties to update.")]
|
||||
TrackingType m_TrackingType;
|
||||
/// <summary>
|
||||
/// The tracking type being used by the Tracked Pose Driver
|
||||
/// to control which <see cref="Transform"/> properties to update.
|
||||
/// </summary>
|
||||
/// <seealso cref="TrackingType"/>
|
||||
public TrackingType trackingType
|
||||
{
|
||||
get => m_TrackingType;
|
||||
set => m_TrackingType = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for which phases of the player loop will update <see cref="Transform"/> properties.
|
||||
/// </summary>
|
||||
/// <seealso cref="updateType"/>
|
||||
/// <seealso cref="InputSystem.onAfterUpdate"/>
|
||||
public enum UpdateType
|
||||
{
|
||||
/// <summary>
|
||||
/// Update after the Input System has completed an update and right before rendering.
|
||||
/// This is the recommended and default option to minimize lag for XR tracked devices.
|
||||
/// </summary>
|
||||
/// <seealso cref="InputUpdateType.BeforeRender"/>
|
||||
UpdateAndBeforeRender,
|
||||
|
||||
/// <summary>
|
||||
/// Update after the Input System has completed an update except right before rendering.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This may be dynamic update, fixed update, or a manual update depending on the Update Mode
|
||||
/// project setting for Input System.
|
||||
/// </remarks>
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// Update after the Input System has completed an update right before rendering.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that this update mode may not trigger if there are no XR devices added which use before render timing.
|
||||
/// </remarks>
|
||||
/// <seealso cref="InputUpdateType.BeforeRender"/>
|
||||
/// <seealso cref="InputDevice.updateBeforeRender"/>
|
||||
BeforeRender,
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("Updates the Transform properties after these phases of Input System event processing.")]
|
||||
UpdateType m_UpdateType = UpdateType.UpdateAndBeforeRender;
|
||||
/// <summary>
|
||||
/// The update type being used by the Tracked Pose Driver
|
||||
/// to control which phases of the player loop will update <see cref="Transform"/> properties.
|
||||
/// </summary>
|
||||
/// <seealso cref="UpdateType"/>
|
||||
public UpdateType updateType
|
||||
{
|
||||
get => m_UpdateType;
|
||||
set => m_UpdateType = value;
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("Ignore Tracking State and always treat the input pose as valid.")]
|
||||
bool m_IgnoreTrackingState;
|
||||
/// <summary>
|
||||
/// Ignore tracking state and always treat the input pose as valid when updating the <see cref="Transform"/> properties.
|
||||
/// The recommended value is <see langword="false"/> so the tracking state input is used.
|
||||
/// </summary>
|
||||
/// <seealso cref="trackingStateInput"/>
|
||||
public bool ignoreTrackingState
|
||||
{
|
||||
get => m_IgnoreTrackingState;
|
||||
set => m_IgnoreTrackingState = value;
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("The input action to read the position value of a tracked device. Must be a Vector 3 control type.")]
|
||||
InputActionProperty m_PositionInput;
|
||||
/// <summary>
|
||||
/// The input action to read the position value of a tracked device.
|
||||
/// Must support reading a value of type <see cref="Vector3"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="rotationInput"/>
|
||||
public InputActionProperty positionInput
|
||||
{
|
||||
get => m_PositionInput;
|
||||
set
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
UnbindPosition();
|
||||
|
||||
m_PositionInput = value;
|
||||
|
||||
if (Application.isPlaying && isActiveAndEnabled)
|
||||
BindPosition();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("The input action to read the rotation value of a tracked device. Must be a Quaternion control type.")]
|
||||
InputActionProperty m_RotationInput;
|
||||
/// <summary>
|
||||
/// The input action to read the rotation value of a tracked device.
|
||||
/// Must support reading a value of type <see cref="Quaternion"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="positionInput"/>
|
||||
public InputActionProperty rotationInput
|
||||
{
|
||||
get => m_RotationInput;
|
||||
set
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
UnbindRotation();
|
||||
|
||||
m_RotationInput = value;
|
||||
|
||||
if (Application.isPlaying && isActiveAndEnabled)
|
||||
BindRotation();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, Tooltip("The input action to read the tracking state value of a tracked device. Identifies if position and rotation have valid data. Must be an Integer control type.")]
|
||||
InputActionProperty m_TrackingStateInput;
|
||||
/// <summary>
|
||||
/// The input action to read the tracking state value of a tracked device.
|
||||
/// Identifies if position and rotation have valid data.
|
||||
/// Must support reading a value of type <see cref="int"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See [InputTrackingState](xref:UnityEngine.XR.InputTrackingState) enum for values the input action represents.
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <term>[InputTrackingState.None](xref:UnityEngine.XR.InputTrackingState.None) (0)</term>
|
||||
/// <description>to indicate neither position nor rotation is valid.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>[InputTrackingState.Position](xref:UnityEngine.XR.InputTrackingState.Position) (1)</term>
|
||||
/// <description>to indicate position is valid.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>[InputTrackingState.Rotation](xref:UnityEngine.XR.InputTrackingState.Rotation) (2)</term>
|
||||
/// <description>to indicate rotation is valid.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>[InputTrackingState.Position](xref:UnityEngine.XR.InputTrackingState.Position) <c>|</c> [InputTrackingState.Rotation](xref:UnityEngine.XR.InputTrackingState.Rotation) (3)</term>
|
||||
/// <description>to indicate position and rotation is valid.</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <seealso cref="ignoreTrackingState"/>
|
||||
public InputActionProperty trackingStateInput
|
||||
{
|
||||
get => m_TrackingStateInput;
|
||||
set
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
UnbindTrackingState();
|
||||
|
||||
m_TrackingStateInput = value;
|
||||
|
||||
if (Application.isPlaying && isActiveAndEnabled)
|
||||
BindTrackingState();
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 m_CurrentPosition = Vector3.zero;
|
||||
Quaternion m_CurrentRotation = Quaternion.identity;
|
||||
TrackingStates m_CurrentTrackingState = TrackingStates.Position | TrackingStates.Rotation;
|
||||
bool m_RotationBound;
|
||||
bool m_PositionBound;
|
||||
bool m_TrackingStateBound;
|
||||
bool m_IsFirstUpdate = true;
|
||||
|
||||
void BindActions()
|
||||
{
|
||||
BindPosition();
|
||||
BindRotation();
|
||||
BindTrackingState();
|
||||
}
|
||||
|
||||
void UnbindActions()
|
||||
{
|
||||
UnbindPosition();
|
||||
UnbindRotation();
|
||||
UnbindTrackingState();
|
||||
}
|
||||
|
||||
void BindPosition()
|
||||
{
|
||||
if (m_PositionBound)
|
||||
return;
|
||||
|
||||
var action = m_PositionInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
action.performed += OnPositionPerformed;
|
||||
action.canceled += OnPositionCanceled;
|
||||
m_PositionBound = true;
|
||||
|
||||
if (m_PositionInput.reference == null)
|
||||
{
|
||||
RenameAndEnable(action, $"{gameObject.name} - TPD - Position");
|
||||
}
|
||||
}
|
||||
|
||||
void BindRotation()
|
||||
{
|
||||
if (m_RotationBound)
|
||||
return;
|
||||
|
||||
var action = m_RotationInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
action.performed += OnRotationPerformed;
|
||||
action.canceled += OnRotationCanceled;
|
||||
m_RotationBound = true;
|
||||
|
||||
if (m_RotationInput.reference == null)
|
||||
{
|
||||
RenameAndEnable(action, $"{gameObject.name} - TPD - Rotation");
|
||||
}
|
||||
}
|
||||
|
||||
void BindTrackingState()
|
||||
{
|
||||
if (m_TrackingStateBound)
|
||||
return;
|
||||
|
||||
var action = m_TrackingStateInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
action.performed += OnTrackingStatePerformed;
|
||||
action.canceled += OnTrackingStateCanceled;
|
||||
m_TrackingStateBound = true;
|
||||
|
||||
if (m_TrackingStateInput.reference == null)
|
||||
{
|
||||
RenameAndEnable(action, $"{gameObject.name} - TPD - Tracking State");
|
||||
}
|
||||
}
|
||||
|
||||
private void RenameAndEnable(InputAction action, string name)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Editor.InputExitPlayModeAnalytic.suppress = true;
|
||||
#endif
|
||||
action.Rename(name);
|
||||
#if UNITY_EDITOR
|
||||
Editor.InputExitPlayModeAnalytic.suppress = false;
|
||||
#endif
|
||||
action.Enable();
|
||||
}
|
||||
|
||||
void UnbindPosition()
|
||||
{
|
||||
if (!m_PositionBound)
|
||||
return;
|
||||
|
||||
var action = m_PositionInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
if (m_PositionInput.reference == null)
|
||||
action.Disable();
|
||||
|
||||
action.performed -= OnPositionPerformed;
|
||||
action.canceled -= OnPositionCanceled;
|
||||
m_PositionBound = false;
|
||||
}
|
||||
|
||||
void UnbindRotation()
|
||||
{
|
||||
if (!m_RotationBound)
|
||||
return;
|
||||
|
||||
var action = m_RotationInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
if (m_RotationInput.reference == null)
|
||||
action.Disable();
|
||||
|
||||
action.performed -= OnRotationPerformed;
|
||||
action.canceled -= OnRotationCanceled;
|
||||
m_RotationBound = false;
|
||||
}
|
||||
|
||||
void UnbindTrackingState()
|
||||
{
|
||||
if (!m_TrackingStateBound)
|
||||
return;
|
||||
|
||||
var action = m_TrackingStateInput.action;
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
if (m_TrackingStateInput.reference == null)
|
||||
action.Disable();
|
||||
|
||||
action.performed -= OnTrackingStatePerformed;
|
||||
action.canceled -= OnTrackingStateCanceled;
|
||||
m_TrackingStateBound = false;
|
||||
}
|
||||
|
||||
void OnPositionPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentPosition = context.ReadValue<Vector3>();
|
||||
}
|
||||
|
||||
void OnPositionCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentPosition = Vector3.zero;
|
||||
}
|
||||
|
||||
void OnRotationPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentRotation = context.ReadValue<Quaternion>();
|
||||
}
|
||||
|
||||
void OnRotationCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
void OnTrackingStatePerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentTrackingState = (TrackingStates)context.ReadValue<int>();
|
||||
}
|
||||
|
||||
void OnTrackingStateCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
m_CurrentTrackingState = TrackingStates.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the user hits the Reset button in the Inspector's context menu
|
||||
/// or when adding the component the first time. This function is only called in editor mode.
|
||||
/// </summary>
|
||||
protected void Reset()
|
||||
{
|
||||
m_PositionInput = new InputActionProperty(new InputAction("Position", expectedControlType: "Vector3"));
|
||||
m_RotationInput = new InputActionProperty(new InputAction("Rotation", expectedControlType: "Quaternion"));
|
||||
m_TrackingStateInput = new InputActionProperty(new InputAction("Tracking State", expectedControlType: "Integer"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the script instance is being loaded.
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_VR && ENABLE_VR
|
||||
if (HasStereoCamera(out var cameraComponent))
|
||||
{
|
||||
UnityEngine.XR.XRDevice.DisableAutoXRCameraTracking(cameraComponent, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
protected void OnEnable()
|
||||
{
|
||||
InputSystem.onAfterUpdate += UpdateCallback;
|
||||
BindActions();
|
||||
|
||||
// Read current input values when becoming enabled,
|
||||
// but wait until after the input update so the input is read at a consistent time
|
||||
m_IsFirstUpdate = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes disabled or inactive.
|
||||
/// </summary>
|
||||
protected void OnDisable()
|
||||
{
|
||||
UnbindActions();
|
||||
InputSystem.onAfterUpdate -= UpdateCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the <see cref="MonoBehaviour"/> will be destroyed.
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
#if UNITY_INPUT_SYSTEM_ENABLE_VR && ENABLE_VR
|
||||
if (HasStereoCamera(out var cameraComponent))
|
||||
{
|
||||
UnityEngine.XR.XRDevice.DisableAutoXRCameraTracking(cameraComponent, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The callback method called after the Input System has completed an update and processed all pending events.
|
||||
/// </summary>
|
||||
/// <seealso cref="InputSystem.onAfterUpdate"/>
|
||||
protected void UpdateCallback()
|
||||
{
|
||||
if (m_IsFirstUpdate)
|
||||
{
|
||||
// Update current input values if this is the first update since becoming enabled
|
||||
// since the performed callbacks may not have been executed
|
||||
if (m_PositionInput.action != null)
|
||||
m_CurrentPosition = m_PositionInput.action.ReadValue<Vector3>();
|
||||
|
||||
if (m_RotationInput.action != null)
|
||||
m_CurrentRotation = m_RotationInput.action.ReadValue<Quaternion>();
|
||||
|
||||
ReadTrackingState();
|
||||
|
||||
m_IsFirstUpdate = false;
|
||||
}
|
||||
|
||||
if (InputState.currentUpdateType == InputUpdateType.BeforeRender)
|
||||
OnBeforeRender();
|
||||
else
|
||||
OnUpdate();
|
||||
}
|
||||
|
||||
void ReadTrackingState()
|
||||
{
|
||||
var trackingStateAction = m_TrackingStateInput.action;
|
||||
if (trackingStateAction != null && !trackingStateAction.enabled)
|
||||
{
|
||||
// Treat a disabled action as the default None value for the ReadValue call
|
||||
m_CurrentTrackingState = TrackingStates.None;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trackingStateAction == null || trackingStateAction.m_BindingsCount == 0)
|
||||
{
|
||||
// Treat an Input Action Reference with no reference the same as
|
||||
// an enabled Input Action with no authored bindings, and allow driving the Transform pose.
|
||||
m_CurrentTrackingState = TrackingStates.Position | TrackingStates.Rotation;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab state.
|
||||
var actionMap = trackingStateAction.GetOrCreateActionMap();
|
||||
actionMap.ResolveBindingsIfNecessary();
|
||||
var state = actionMap.m_State;
|
||||
|
||||
// Get list of resolved controls to determine if a device actually has tracking state.
|
||||
var hasResolvedControl = false;
|
||||
if (state != null)
|
||||
{
|
||||
var actionIndex = trackingStateAction.m_ActionIndexInState;
|
||||
var totalBindingCount = state.totalBindingCount;
|
||||
for (var i = 0; i < totalBindingCount; ++i)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
ref var bindingState = ref state.bindingStates[i];
|
||||
if (bindingState.actionIndex != actionIndex)
|
||||
continue;
|
||||
if (bindingState.isComposite)
|
||||
continue;
|
||||
|
||||
if (bindingState.controlCount > 0)
|
||||
{
|
||||
hasResolvedControl = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retain the current value if there is no resolved binding.
|
||||
// Since the field initializes to allowing position and rotation,
|
||||
// this allows for driving the Transform pose always when the device
|
||||
// doesn't support reporting the tracking state.
|
||||
if (hasResolvedControl)
|
||||
m_CurrentTrackingState = (TrackingStates)trackingStateAction.ReadValue<int>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called after the Input System has completed an update and processed all pending events
|
||||
/// when the type of update is not <see cref="InputUpdateType.BeforeRender"/>.
|
||||
/// </summary>
|
||||
protected virtual void OnUpdate()
|
||||
{
|
||||
if (m_UpdateType == UpdateType.Update ||
|
||||
m_UpdateType == UpdateType.UpdateAndBeforeRender)
|
||||
{
|
||||
PerformUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called after the Input System has completed an update and processed all pending events
|
||||
/// when the type of update is <see cref="InputUpdateType.BeforeRender"/>.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeRender()
|
||||
{
|
||||
if (m_UpdateType == UpdateType.BeforeRender ||
|
||||
m_UpdateType == UpdateType.UpdateAndBeforeRender)
|
||||
{
|
||||
PerformUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates <see cref="Transform"/> properties with the current input pose values that have been read,
|
||||
/// constrained by tracking type and tracking state.
|
||||
/// </summary>
|
||||
/// <seealso cref="SetLocalTransform"/>
|
||||
protected virtual void PerformUpdate()
|
||||
{
|
||||
SetLocalTransform(m_CurrentPosition, m_CurrentRotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates <see cref="Transform"/> properties, constrained by tracking type and tracking state.
|
||||
/// </summary>
|
||||
/// <param name="newPosition">The new local position to possibly set.</param>
|
||||
/// <param name="newRotation">The new local rotation to possibly set.</param>
|
||||
protected virtual void SetLocalTransform(Vector3 newPosition, Quaternion newRotation)
|
||||
{
|
||||
var positionValid = m_IgnoreTrackingState || (m_CurrentTrackingState & TrackingStates.Position) != 0;
|
||||
var rotationValid = m_IgnoreTrackingState || (m_CurrentTrackingState & TrackingStates.Rotation) != 0;
|
||||
|
||||
#if HAS_SET_LOCAL_POSITION_AND_ROTATION
|
||||
if (m_TrackingType == TrackingType.RotationAndPosition && rotationValid && positionValid)
|
||||
{
|
||||
transform.SetLocalPositionAndRotation(newPosition, newRotation);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rotationValid &&
|
||||
(m_TrackingType == TrackingType.RotationAndPosition ||
|
||||
m_TrackingType == TrackingType.RotationOnly))
|
||||
{
|
||||
transform.localRotation = newRotation;
|
||||
}
|
||||
|
||||
if (positionValid &&
|
||||
(m_TrackingType == TrackingType.RotationAndPosition ||
|
||||
m_TrackingType == TrackingType.PositionOnly))
|
||||
{
|
||||
transform.localPosition = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
bool HasStereoCamera(out Camera cameraComponent)
|
||||
{
|
||||
return TryGetComponent(out cameraComponent) && cameraComponent.stereoEnabled;
|
||||
}
|
||||
|
||||
#region DEPRECATED
|
||||
|
||||
// Disable warnings that these fields are never assigned to. They are set during Unity deserialization and migrated.
|
||||
// ReSharper disable UnassignedField.Local
|
||||
#pragma warning disable 0649
|
||||
[Obsolete]
|
||||
[SerializeField, HideInInspector]
|
||||
InputAction m_PositionAction;
|
||||
/// <summary>
|
||||
/// (Deprecated) The action to read the position value of a tracked device.
|
||||
/// Must support reading a value of type <see cref="Vector3"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="positionInput"/>
|
||||
public InputAction positionAction
|
||||
{
|
||||
get => m_PositionInput.action;
|
||||
set => positionInput = new InputActionProperty(value);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
[SerializeField, HideInInspector]
|
||||
InputAction m_RotationAction;
|
||||
/// <summary>
|
||||
/// (Deprecated) The action to read the rotation value of a tracked device.
|
||||
/// Must support reading a value of type <see cref="Quaternion"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="rotationInput"/>
|
||||
public InputAction rotationAction
|
||||
{
|
||||
get => m_RotationInput.action;
|
||||
set => rotationInput = new InputActionProperty(value);
|
||||
}
|
||||
#pragma warning restore 0649
|
||||
// ReSharper restore UnassignedField.Local
|
||||
|
||||
/// <inheritdoc />
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
#pragma warning disable 0612 // Type or member is obsolete -- Deprecated fields are migrated to new properties.
|
||||
#pragma warning disable UNT0029 // Pattern matching with null on Unity objects -- Using true null is intentional, not operator== evaluation.
|
||||
// We're checking for true null here since we don't want to migrate if the new field is already being used, even if the reference is missing.
|
||||
// Migrate the old fields to the new properties added in Input System 1.1.0-pre.6.
|
||||
if (m_PositionInput.serializedReference is null && m_PositionInput.serializedAction is null && !(m_PositionAction is null))
|
||||
m_PositionInput = new InputActionProperty(m_PositionAction);
|
||||
|
||||
if (m_RotationInput.serializedReference is null && m_RotationInput.serializedAction is null && !(m_RotationAction is null))
|
||||
m_RotationInput = new InputActionProperty(m_RotationAction);
|
||||
#pragma warning restore UNT0029
|
||||
#pragma warning restore 0612
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2fadf230d1919748a9aa21d40f74619
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 7b8bfaee8f8631c4789ac62373cbc2d4, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,344 @@
|
||||
// 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) && !UNITY_FORCE_INPUTSYSTEM_XR_OFF
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
using System.Text;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace UnityEngine.InputSystem.XR
|
||||
{
|
||||
internal class XRLayoutBuilder
|
||||
{
|
||||
private string parentLayout;
|
||||
private string interfaceName;
|
||||
private XRDeviceDescriptor descriptor;
|
||||
|
||||
private static uint GetSizeOfFeature(XRFeatureDescriptor featureDescriptor)
|
||||
{
|
||||
switch (featureDescriptor.featureType)
|
||||
{
|
||||
case FeatureType.Binary:
|
||||
return sizeof(byte);
|
||||
case FeatureType.DiscreteStates:
|
||||
return sizeof(int);
|
||||
case FeatureType.Axis1D:
|
||||
return sizeof(float);
|
||||
case FeatureType.Axis2D:
|
||||
return sizeof(float) * 2;
|
||||
case FeatureType.Axis3D:
|
||||
return sizeof(float) * 3;
|
||||
case FeatureType.Rotation:
|
||||
return sizeof(float) * 4;
|
||||
case FeatureType.Hand:
|
||||
return sizeof(uint) * 26;
|
||||
case FeatureType.Bone:
|
||||
return sizeof(uint) + (sizeof(float) * 3) + (sizeof(float) * 4);
|
||||
case FeatureType.Eyes:
|
||||
return (sizeof(float) * 3) * 3 + ((sizeof(float) * 4) * 2) + (sizeof(float) * 2);
|
||||
case FeatureType.Custom:
|
||||
return featureDescriptor.customSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static string SanitizeString(string original, bool allowPaths = false)
|
||||
{
|
||||
var stringLength = original.Length;
|
||||
var sanitizedName = new StringBuilder(stringLength);
|
||||
for (var i = 0; i < stringLength; i++)
|
||||
{
|
||||
var letter = original[i];
|
||||
if (char.IsUpper(letter) || char.IsLower(letter) || char.IsDigit(letter) || letter == '_' || (allowPaths && (letter == '/')))
|
||||
{
|
||||
sanitizedName.Append(letter);
|
||||
}
|
||||
}
|
||||
return sanitizedName.ToString();
|
||||
}
|
||||
|
||||
internal static string OnFindLayoutForDevice(ref InputDeviceDescription description, string matchedLayout,
|
||||
InputDeviceExecuteCommandDelegate executeCommandDelegate)
|
||||
{
|
||||
// If the device isn't a XRInput, we're not interested.
|
||||
if (description.interfaceName != XRUtilities.InterfaceCurrent && description.interfaceName != XRUtilities.InterfaceV1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the description doesn't come with a XR SDK descriptor, we're not
|
||||
// interested either.
|
||||
if (string.IsNullOrEmpty(description.capabilities))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Try to parse the XR descriptor.
|
||||
XRDeviceDescriptor deviceDescriptor;
|
||||
try
|
||||
{
|
||||
deviceDescriptor = XRDeviceDescriptor.FromJson(description.capabilities);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (deviceDescriptor == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(matchedLayout))
|
||||
{
|
||||
const InputDeviceCharacteristics controllerCharacteristics = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Controller;
|
||||
if ((deviceDescriptor.characteristics & InputDeviceCharacteristics.HeadMounted) != 0)
|
||||
matchedLayout = "XRHMD";
|
||||
else if ((deviceDescriptor.characteristics & controllerCharacteristics) == controllerCharacteristics)
|
||||
matchedLayout = "XRController";
|
||||
}
|
||||
|
||||
string layoutName;
|
||||
if (string.IsNullOrEmpty(description.manufacturer))
|
||||
{
|
||||
layoutName = $"{SanitizeString(description.interfaceName)}::{SanitizeString(description.product)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
layoutName =
|
||||
$"{SanitizeString(description.interfaceName)}::{SanitizeString(description.manufacturer)}::{SanitizeString(description.product)}";
|
||||
}
|
||||
|
||||
var layout = new XRLayoutBuilder { descriptor = deviceDescriptor, parentLayout = matchedLayout, interfaceName = description.interfaceName };
|
||||
InputSystem.RegisterLayoutBuilder(() => layout.Build(), layoutName, matchedLayout);
|
||||
|
||||
return layoutName;
|
||||
}
|
||||
|
||||
private static string ConvertPotentialAliasToName(InputControlLayout layout, string nameOrAlias)
|
||||
{
|
||||
var internedNameOrAlias = new InternedString(nameOrAlias);
|
||||
var controls = layout.controls;
|
||||
for (var i = 0; i < controls.Count; i++)
|
||||
{
|
||||
var controlItem = controls[i];
|
||||
|
||||
if (controlItem.name == internedNameOrAlias)
|
||||
return nameOrAlias;
|
||||
|
||||
var aliases = controlItem.aliases;
|
||||
for (var j = 0; j < aliases.Count; j++)
|
||||
{
|
||||
if (aliases[j] == nameOrAlias)
|
||||
return controlItem.name.ToString();
|
||||
}
|
||||
}
|
||||
return nameOrAlias;
|
||||
}
|
||||
|
||||
private bool IsSubControl(string name)
|
||||
{
|
||||
return name.Contains('/');
|
||||
}
|
||||
|
||||
private string GetParentControlName(string name)
|
||||
{
|
||||
int idx = name.IndexOf('/');
|
||||
return name.Substring(0, idx);
|
||||
}
|
||||
|
||||
static readonly string[] poseSubControlNames =
|
||||
{
|
||||
"/isTracked",
|
||||
"/trackingState",
|
||||
"/position",
|
||||
"/rotation",
|
||||
"/velocity",
|
||||
"/angularVelocity"
|
||||
};
|
||||
|
||||
static readonly FeatureType[] poseSubControlTypes =
|
||||
{
|
||||
FeatureType.Binary,
|
||||
FeatureType.DiscreteStates,
|
||||
FeatureType.Axis3D,
|
||||
FeatureType.Rotation,
|
||||
FeatureType.Axis3D,
|
||||
FeatureType.Axis3D
|
||||
};
|
||||
|
||||
// A PoseControl consists of 6 subcontrols with specific names and types
|
||||
private bool IsPoseControl(List<XRFeatureDescriptor> features, int startIndex)
|
||||
{
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
if (!features[startIndex + i].name.EndsWith(poseSubControlNames[i]) ||
|
||||
features[startIndex + i].featureType != poseSubControlTypes[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private InputControlLayout Build()
|
||||
{
|
||||
var builder = new InputControlLayout.Builder
|
||||
{
|
||||
stateFormat = new FourCC('X', 'R', 'S', '0'),
|
||||
extendsLayout = parentLayout,
|
||||
updateBeforeRender = true
|
||||
};
|
||||
|
||||
var inheritedLayout = !string.IsNullOrEmpty(parentLayout)
|
||||
? InputSystem.LoadLayout(parentLayout)
|
||||
: null;
|
||||
|
||||
var parentControls = new List<string>();
|
||||
var currentUsages = new List<string>();
|
||||
|
||||
uint currentOffset = 0;
|
||||
for (var i = 0; i < descriptor.inputFeatures.Count; i++)
|
||||
{
|
||||
var feature = descriptor.inputFeatures[i];
|
||||
currentUsages.Clear();
|
||||
|
||||
if (feature.usageHints != null)
|
||||
{
|
||||
foreach (var usageHint in feature.usageHints)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(usageHint.content))
|
||||
currentUsages.Add(usageHint.content);
|
||||
}
|
||||
}
|
||||
|
||||
var featureName = feature.name;
|
||||
featureName = SanitizeString(featureName, true);
|
||||
if (inheritedLayout != null)
|
||||
featureName = ConvertPotentialAliasToName(inheritedLayout, featureName);
|
||||
|
||||
featureName = featureName.ToLower();
|
||||
|
||||
if (IsSubControl(featureName))
|
||||
{
|
||||
string parentControl = GetParentControlName(featureName);
|
||||
if (!parentControls.Contains(parentControl))
|
||||
{
|
||||
if (IsPoseControl(descriptor.inputFeatures, i))
|
||||
{
|
||||
builder.AddControl(parentControl)
|
||||
.WithLayout("Pose")
|
||||
.WithByteOffset(0);
|
||||
parentControls.Add(parentControl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint nextOffset = GetSizeOfFeature(feature);
|
||||
if (interfaceName == XRUtilities.InterfaceV1)
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
if (nextOffset < 4)
|
||||
nextOffset = 4;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextOffset >= 4 && (currentOffset % 4 != 0))
|
||||
currentOffset += (4 - (currentOffset % 4));
|
||||
}
|
||||
|
||||
|
||||
switch (feature.featureType)
|
||||
{
|
||||
case FeatureType.Binary:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Button")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatBit)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.DiscreteStates:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Integer")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatInt)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Axis1D:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Analog")
|
||||
.WithRange(-1, 1)
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatFloat)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Axis2D:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Stick")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatVector2)
|
||||
.WithUsages(currentUsages);
|
||||
|
||||
builder.AddControl(featureName + "/x")
|
||||
.WithLayout("Analog")
|
||||
.WithRange(-1, 1);
|
||||
builder.AddControl(featureName + "/y")
|
||||
.WithLayout("Analog")
|
||||
.WithRange(-1, 1);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Axis3D:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Vector3")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatVector3)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Rotation:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Quaternion")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithFormat(InputStateBlock.FormatQuaternion)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Hand:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case FeatureType.Bone:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Bone")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
case FeatureType.Eyes:
|
||||
{
|
||||
builder.AddControl(featureName)
|
||||
.WithLayout("Eyes")
|
||||
.WithByteOffset(currentOffset)
|
||||
.WithUsages(currentUsages);
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentOffset += nextOffset;
|
||||
}
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f06ed8c4023b8420784a262e45338aa3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,509 @@
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of static utilities for registering XR Input Devices externally.
|
||||
/// </summary>
|
||||
public static class XRUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple Regex pattern that allows InputDeviceMatchers to match to any version of the XRInput interface.
|
||||
/// </summary>
|
||||
public const string InterfaceMatchAnyVersion = "^(XRInput)";
|
||||
|
||||
/// <summary>
|
||||
/// The initial, now deprecated interface for XRInput. This version handles button packing for Android differently from current.
|
||||
/// </summary>
|
||||
public const string InterfaceV1 = "XRInput";
|
||||
|
||||
/// <summary>
|
||||
/// The current interface code sent with devices to identify as XRInput devices.
|
||||
/// </summary>
|
||||
public const string InterfaceCurrent = "XRInputV1";
|
||||
}
|
||||
|
||||
// Sync to UnityXRInputFeatureType in IUnityXRInput.h
|
||||
/// <summary>
|
||||
/// The type of data a <see cref="XRFeatureDescriptor"/> exposes.
|
||||
/// </summary>
|
||||
public enum FeatureType
|
||||
{
|
||||
Custom = 0,
|
||||
Binary,
|
||||
DiscreteStates,
|
||||
Axis1D,
|
||||
Axis2D,
|
||||
Axis3D,
|
||||
Rotation,
|
||||
Hand,
|
||||
Bone,
|
||||
Eyes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contextual strings that identify the contextual, cross-platform use that a feature represents. <see cref="UnityEngine.XR.CommonUsages"/> for a list of unity's built-in shared usages.
|
||||
/// </summary>
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct UsageHint
|
||||
{
|
||||
public string content;
|
||||
}
|
||||
|
||||
//Sync to XRInputFeatureDefinition in XRInputDeviceDefinition.h
|
||||
/// <summary>
|
||||
/// Describes an individual input on a device, such as a trackpad, or button, or trigger.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct XRFeatureDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the feature.
|
||||
/// </summary>
|
||||
public string name;
|
||||
/// <summary>
|
||||
/// The uses that this feature should represent, such as trigger, or grip, or touchpad.
|
||||
/// </summary>
|
||||
public List<UsageHint> usageHints;
|
||||
/// <summary>
|
||||
/// The type of data this feature exposes.
|
||||
/// </summary>
|
||||
public FeatureType featureType;
|
||||
/// <summary>
|
||||
/// The overall size of the feature. This is only filled in when the <see cref="featureType"/> is <see cref="FeatureType.Custom"/>.
|
||||
/// </summary>
|
||||
public uint customSize;
|
||||
}
|
||||
|
||||
//Sync to XRInputDeviceDefinition in XRInputDeviceDefinition.h
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class XRDeviceDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the device.
|
||||
/// </summary>
|
||||
public string deviceName;
|
||||
/// <summary>
|
||||
/// The manufacturer of the device.
|
||||
/// </summary>
|
||||
public string manufacturer;
|
||||
/// <summary>
|
||||
/// The serial number of the device. An empty string if no serial number is available.
|
||||
/// </summary>
|
||||
public string serialNumber;
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
public InputDeviceCharacteristics characteristics;
|
||||
/// <summary>
|
||||
/// The underlying deviceId, this can be used with <see cref="UnityEngine.XR.InputDevices"/> to create a device.
|
||||
/// </summary>
|
||||
public int deviceId;
|
||||
/// <summary>
|
||||
/// A list of all input features. <seealso cref="XRFeatureDescriptor"/>
|
||||
/// </summary>
|
||||
public List<XRFeatureDescriptor> inputFeatures;
|
||||
|
||||
/// <summary>
|
||||
/// Converts this structure to a JSON string.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToJson()
|
||||
{
|
||||
return JsonUtility.ToJson(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a json string to a new <see cref="XRDeviceDescriptor"/>.
|
||||
/// </summary>
|
||||
/// <param name="json">The JSON string containing <see cref="XRDeviceDescriptor"/> data.</param>
|
||||
/// <returns>A new <see cref="XRDeviceDescriptor"/></returns>
|
||||
public static XRDeviceDescriptor FromJson(string json)
|
||||
{
|
||||
return JsonUtility.FromJson<XRDeviceDescriptor>(json);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a 3 dimensional, tracked bone within a hierarchy of other bones.
|
||||
/// </summary>
|
||||
public struct Bone
|
||||
{
|
||||
/// <summary>
|
||||
/// The index with the device's controls array where the parent bone resides.
|
||||
/// </summary>
|
||||
public uint m_ParentBoneIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The tracked position of the bone.
|
||||
/// </summary>
|
||||
public Vector3 m_Position;
|
||||
|
||||
/// <summary>
|
||||
/// The tracked rotation of the bone.
|
||||
/// </summary>
|
||||
public Quaternion m_Rotation;
|
||||
|
||||
/// <summary>
|
||||
/// The index with the device's controls array where the parent bone resides.
|
||||
/// </summary>
|
||||
public uint parentBoneIndex
|
||||
{
|
||||
get => m_ParentBoneIndex;
|
||||
set => m_ParentBoneIndex = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tracked position of the bone.
|
||||
/// </summary>
|
||||
public Vector3 position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tracked rotation of the bone.
|
||||
/// </summary>
|
||||
public Quaternion rotation
|
||||
{
|
||||
get => m_Rotation;
|
||||
set => m_Rotation = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a pair of tracked eyes.
|
||||
/// </summary>
|
||||
public struct Eyes
|
||||
{
|
||||
/// <summary>
|
||||
/// The tracked position of the left eye.
|
||||
/// </summary>
|
||||
public Vector3 m_LeftEyePosition;
|
||||
/// <summary>
|
||||
/// The tracked rotation of the left eye.
|
||||
/// </summary>
|
||||
public Quaternion m_LeftEyeRotation;
|
||||
/// <summary>
|
||||
/// The tracked position of the right eye.
|
||||
/// </summary>
|
||||
public Vector3 m_RightEyePosition;
|
||||
/// <summary>
|
||||
/// The tracked rotation of the right eye.
|
||||
/// </summary>
|
||||
public Quaternion m_RightEyeRotation;
|
||||
/// <summary>
|
||||
/// The point in 3D space that the pair of eyes is looking.
|
||||
/// </summary>
|
||||
public Vector3 m_FixationPoint;
|
||||
/// <summary>
|
||||
/// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
|
||||
/// </summary>
|
||||
public float m_LeftEyeOpenAmount;
|
||||
/// <summary>
|
||||
/// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
|
||||
/// </summary>
|
||||
public float m_RightEyeOpenAmount;
|
||||
|
||||
/// <summary>
|
||||
/// The tracked position of the left eye.
|
||||
/// </summary>
|
||||
public Vector3 leftEyePosition
|
||||
{
|
||||
get => m_LeftEyePosition;
|
||||
set => m_LeftEyePosition = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tracked rotation of the left eye.
|
||||
/// </summary>
|
||||
public Quaternion leftEyeRotation
|
||||
{
|
||||
get => m_LeftEyeRotation;
|
||||
set => m_LeftEyeRotation = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tracked position of the right eye.
|
||||
/// </summary>
|
||||
public Vector3 rightEyePosition
|
||||
{
|
||||
get => m_RightEyePosition;
|
||||
set => m_RightEyePosition = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tracked rotation of the right eye.
|
||||
/// </summary>
|
||||
public Quaternion rightEyeRotation
|
||||
{
|
||||
get => m_RightEyeRotation;
|
||||
set => m_RightEyeRotation = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The point in 3D space that the pair of eyes is looking.
|
||||
/// </summary>
|
||||
public Vector3 fixationPoint
|
||||
{
|
||||
get => m_FixationPoint;
|
||||
set => m_FixationPoint = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
|
||||
/// </summary>
|
||||
public float leftEyeOpenAmount
|
||||
{
|
||||
get => m_LeftEyeOpenAmount;
|
||||
set => m_LeftEyeOpenAmount = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
|
||||
/// </summary>
|
||||
public float rightEyeOpenAmount
|
||||
{
|
||||
get => m_RightEyeOpenAmount;
|
||||
set => m_RightEyeOpenAmount = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class BoneControl : InputControl<Bone>
|
||||
{
|
||||
[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<IntegerControl>("parentBoneIndex");
|
||||
position = GetChildControl<Vector3Control>("position");
|
||||
rotation = GetChildControl<QuaternionControl>("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<Eyes>
|
||||
{
|
||||
[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<Vector3Control>("leftEyePosition");
|
||||
leftEyeRotation = GetChildControl<QuaternionControl>("leftEyeRotation");
|
||||
rightEyePosition = GetChildControl<Vector3Control>("rightEyePosition");
|
||||
rightEyeRotation = GetChildControl<QuaternionControl>("rightEyeRotation");
|
||||
fixationPoint = GetChildControl<Vector3Control>("fixationPoint");
|
||||
leftEyeOpenAmount = GetChildControl<AxisControl>("leftEyeOpenAmount");
|
||||
rightEyeOpenAmount = GetChildControl<AxisControl>("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
|
||||
|
||||
/// <summary>
|
||||
/// A small helper class to aid in initializing and registering XR devices and layout builders.
|
||||
/// </summary>
|
||||
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
|
||||
public
|
||||
#else
|
||||
internal
|
||||
#endif
|
||||
static class XRSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers all initial templates and the generalized layout builder with the InputSystem.
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
#if !UNITY_FORCE_INPUTSYSTEM_XR_OFF
|
||||
InputSystem.RegisterLayout<PoseControl>("Pose");
|
||||
InputSystem.RegisterLayout<BoneControl>("Bone");
|
||||
InputSystem.RegisterLayout<EyesControl>("Eyes");
|
||||
|
||||
InputSystem.RegisterLayout<XRHMD>();
|
||||
InputSystem.RegisterLayout<XRController>();
|
||||
|
||||
InputSystem.onFindLayoutForDevice += XRLayoutBuilder.OnFindLayoutForDevice;
|
||||
|
||||
// Built-in layouts replaced by the com.unity.xr.windowsmr package.
|
||||
#if !DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR
|
||||
InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRHMD>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("(Windows Mixed Reality HMD)|(Microsoft HoloLens)|(^(WindowsMR Headset))")
|
||||
);
|
||||
InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRSpatialController>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(@"(^(Spatial Controller))|(^(OpenVR Controller\(WindowsMR))")
|
||||
);
|
||||
InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.HololensHand>(
|
||||
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<Unity.XR.Oculus.Input.OculusHMD>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("^(Oculus Rift)|^(Oculus Quest)|^(Oculus Go)"));
|
||||
InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTouchController>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(@"(^(Oculus Touch Controller))|(^(Oculus Quest Controller))"));
|
||||
InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusRemote>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(@"Oculus Remote"));
|
||||
InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTrackingReference>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(@"((Tracking Reference)|(^(Oculus Rift [a-zA-Z0-9]* \(Camera)))"));
|
||||
|
||||
InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusHMDExtended>(
|
||||
name: "GearVR",
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("Oculus HMD"));
|
||||
InputSystem.RegisterLayout<Unity.XR.Oculus.Input.GearVRTrackedController>(
|
||||
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<Unity.XR.GoogleVr.DaydreamHMD>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("Daydream HMD"));
|
||||
InputSystem.RegisterLayout<Unity.XR.GoogleVr.DaydreamController>(
|
||||
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<Unity.XR.OpenVR.OpenVRHMD>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("^(OpenVR Headset)|^(Vive Pro)")
|
||||
);
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVRControllerWMR>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct("^(OpenVR Controller\\(WindowsMR)")
|
||||
);
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveWand>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithManufacturer("HTC")
|
||||
.WithProduct(@"^(OpenVR Controller\(((Vive. Controller)|(VIVE. Controller)|(Vive Controller)))")
|
||||
);
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVROculusTouchController>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithProduct(@"^(OpenVR Controller\(Oculus)")
|
||||
);
|
||||
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveTracker>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithManufacturer("HTC")
|
||||
.WithProduct(@"^(VIVE Tracker)")
|
||||
);
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.HandedViveTracker>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithManufacturer("HTC")
|
||||
.WithProduct(@"^(OpenVR Controller\(VIVE Tracker)")
|
||||
);
|
||||
InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveLighthouse>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
|
||||
.WithManufacturer("HTC")
|
||||
.WithProduct(@"^(HTC V2-XD/XE)")
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9be5e04bc92741ccbe2c262bfaa517f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user