namespace UnityEngine.XR.Interaction.Toolkit.Inputs.Readers { /// /// An abstract base that provides a value from a device /// from the XR input subsystem as defined by its characteristics and feature usage string. /// Intended to be used with an as its object reference /// or as part of an . This class contains the common /// base fields of the typed value reader. /// /// public abstract class XRInputDeviceValueReader : ScriptableObject { [SerializeField] [Tooltip("Characteristics of the input device to read from. Controllers are either:" + "\nHeld In Hand, Tracked Device, Controller, Left" + "\nHeld In Hand, Tracked Device, Controller, Right")] private protected InputDeviceCharacteristics m_Characteristics; /// /// Characteristics of the input device to read from. Controllers are either: /// | | | or /// | | | . /// public InputDeviceCharacteristics characteristics { get => m_Characteristics; set => m_Characteristics = value; } } /// /// A that provides a typed value from a device /// from the XR input subsystem as defined by its characteristics and feature usage string. /// Intended to be used with an as its object reference /// or as part of an . /// /// Type of the value to read, such as or . public abstract class XRInputDeviceValueReader : XRInputDeviceValueReader, IXRInputValueReader where TValue : struct { [SerializeField] [Tooltip("The name of the input feature to read.")] InputFeatureUsageString m_Usage; /// /// The name of the input feature usage to read. /// public InputFeatureUsageString usage { get => m_Usage; set => m_Usage = value; } InputDevice m_InputDevice; /// public abstract TValue ReadValue(); /// public abstract bool TryReadValue(out TValue value); /// /// Read the value of the input as a . /// /// Returns the value of the input as a . protected bool ReadBoolValue() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as an . /// /// Returns the value of the input as a . protected uint ReadUIntValue() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as a . /// /// Returns the value of the input as a . protected float ReadFloatValue() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as a . /// /// Returns the value of the input as a . protected Vector2 ReadVector2Value() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as a . /// /// Returns the value of the input as a . protected Vector3 ReadVector3Value() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as a . /// /// Returns the value of the input as a . protected Quaternion ReadQuaternionValue() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Read the value of the input as an . /// /// Returns the value of the input as an . protected InputTrackingState ReadInputTrackingStateValue() { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out var value)) return value; return default; } /// /// Try to read the value of the input as a . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadBoolValue(out bool value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as an . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadUIntValue(out uint value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as a . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadFloatValue(out float value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as a . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadVector2Value(out Vector2 value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as a . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadVector3Value(out Vector3 value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as a . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadQuaternionValue(out Quaternion value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Try to read the value of the input as an . /// /// When this method returns , the value read. Otherwise, the default for the type. /// Returns if the value was successfully read. protected bool TryReadInputTrackingStateValue(out InputTrackingState value) { if (RefreshInputDeviceIfNeeded() && m_InputDevice.TryGetFeatureValue(new InputFeatureUsage(m_Usage.name), out value)) return true; value = default; return false; } /// /// Updates the found input device used to read input from if it isn't valid. /// This should be called before attempting to read a value from the input device. /// /// Returns if the input device is valid or if a valid one with matching characteristics was found. protected bool RefreshInputDeviceIfNeeded() { return m_InputDevice.isValid || XRInputTrackingAggregator.TryGetDeviceWithExactCharacteristics(m_Characteristics, out m_InputDevice); } } }