using UnityEngine.XR.Interaction.Toolkit.Inputs.Readers; namespace UnityEngine.XR.Interaction.Toolkit.Samples.Hands { /// /// Example class that reads a float value from an and converts it to a bool. /// Useful with hand interaction because the bool select value can be unreliable when the hand is near the tight internal threshold. /// [DefaultExecutionOrder(XRInteractionUpdateOrder.k_XRInputDeviceButtonReader)] public class ValueDerivedButtonReader : MonoBehaviour, IXRInputButtonReader { [SerializeField] [Tooltip("The input reader used to reference the float value to convert to a bool.")] XRInputValueReader m_ValueInput = new XRInputValueReader("Value"); /// /// The input reader used to reference the float value to convert to a bool. /// public XRInputValueReader valueInput { get => m_ValueInput; set => XRInputReaderUtility.SetInputProperty(ref m_ValueInput, value, this); } [SerializeField] [Tooltip("The threshold value to use to determine when the button is pressed. Considered pressed equal to or greater than this value.")] [Range(0f, 1f)] float m_PressThreshold = 0.8f; /// /// The threshold value to use to determine when the button is pressed. Considered pressed equal to or greater than this value. /// public float pressThreshold { get => m_PressThreshold; set => m_PressThreshold = value; } [SerializeField] [Tooltip("The threshold value to use to determine when the button is released when it was previously pressed. Keeps being pressed until falls back to a value of or below this value.")] [Range(0f, 1f)] float m_ReleaseThreshold = 0.25f; /// /// The threshold value to use to determine when the button is released when it was previously pressed. /// Keeps being pressed until falls back to a value of or below this value. /// public float releaseThreshold { get => m_ReleaseThreshold; set => m_ReleaseThreshold = value; } bool m_IsPerformed; bool m_WasPerformedThisFrame; bool m_WasCompletedThisFrame; /// /// See . /// void OnEnable() { m_ValueInput?.EnableDirectActionIfModeUsed(); } /// /// See . /// void OnDisable() { m_ValueInput?.DisableDirectActionIfModeUsed(); } /// /// See . /// void Update() { var prevPerformed = m_IsPerformed; var pressAmount = m_ValueInput.ReadValue(); var newValue = pressAmount >= m_PressThreshold; if (!newValue && prevPerformed) newValue = pressAmount > m_ReleaseThreshold; m_IsPerformed = newValue; m_WasPerformedThisFrame = !prevPerformed && m_IsPerformed; m_WasCompletedThisFrame = prevPerformed && !m_IsPerformed; } /// public bool ReadIsPerformed() { return m_IsPerformed; } /// public bool ReadWasPerformedThisFrame() { return m_WasPerformedThisFrame; } /// public bool ReadWasCompletedThisFrame() { return m_WasCompletedThisFrame; } /// public float ReadValue() { return m_ValueInput.ReadValue(); } /// public bool TryReadValue(out float value) { return m_ValueInput.TryReadValue(out value); } } }