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