Initial commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:02:30 +07:00
commit 0a84b9d75e
15481 changed files with 2009655 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 25ea971cc17caa84a8a2fdf9917af7b4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7ada2e545c685b44a8367bdab267f0dc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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: "/&lt;XRController&gt;{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

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8529451a1ee99484a891bdea2f5219f3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

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

View File

@@ -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:

View File

@@ -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

View File

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

View File

@@ -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

View File

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