using UnityEngine.XR.Interaction.Toolkit.Inputs.Readers; namespace UnityEngine.XR.Interaction.Toolkit.Inputs.Haptics { /// /// Component that allows for sending haptic impulses to a device. /// [AddComponentMenu("XR/Haptics/Haptic Impulse Player", 11)] [HelpURL(XRHelpURLConstants.k_HapticImpulsePlayer)] public class HapticImpulsePlayer : MonoBehaviour { [SerializeField] [Tooltip("Specifies the output haptic control or controller that haptic impulses will be sent to.")] XRInputHapticImpulseProvider m_HapticOutput = new XRInputHapticImpulseProvider("Haptic"); /// /// Specifies the output haptic control or controller that haptic impulses will be sent to. /// public XRInputHapticImpulseProvider hapticOutput { get => m_HapticOutput; set => XRInputReaderUtility.SetInputProperty(ref m_HapticOutput, value, this); } [SerializeField, Range(0f, 1f)] [Tooltip("Amplitude multiplier which can be used to dampen the haptic impulses sent by this component.")] float m_AmplitudeMultiplier = 1f; /// /// Amplitude multiplier which can be used to dampen the haptic impulses sent by this component. /// public float amplitudeMultiplier { get => m_AmplitudeMultiplier; set => m_AmplitudeMultiplier = value; } /// /// See . /// protected void Awake() { if (m_HapticOutput is { inputSourceMode: XRInputHapticImpulseProvider.InputSourceMode.InputActionReference } && m_HapticOutput.inputActionReference == null) { var impulseProvider = gameObject.GetComponentInParent(true); if (impulseProvider as Component != null) { m_HapticOutput.SetObjectReference(impulseProvider); m_HapticOutput.inputSourceMode = XRInputHapticImpulseProvider.InputSourceMode.ObjectReference; } } } /// /// See . /// protected void OnEnable() { // Enable and disable directly serialized actions with this behavior's enabled lifecycle. m_HapticOutput.EnableDirectActionIfModeUsed(); } /// /// See . /// protected void OnDisable() { m_HapticOutput.DisableDirectActionIfModeUsed(); } /// /// Sends a haptic impulse on the configured channel or default channel of the configured device. /// /// The desired motor amplitude that should be within a [0-1] range. /// The desired duration of the impulse in seconds. /// Returns if successful. Otherwise, returns . /// /// This method considers sending the haptic impulse a success (and thus returns ) /// if the haptic impulse was successfully sent to the device even if frequency is ignored or not supported by the device. ///
/// Uses the default frequency of the device. ///
public bool SendHapticImpulse(float amplitude, float duration) => SendHapticImpulse(amplitude, duration, 0f); /// /// Sends a haptic impulse on the configured channel or default channel of the configured device. /// /// The desired motor amplitude that should be within a [0-1] range. /// The desired duration of the impulse in seconds. /// The desired frequency of the impulse in Hz. A value of 0 means to use the default frequency of the device. /// Returns if successful. Otherwise, returns . /// /// This method considers sending the haptic impulse a success (and thus returns ) /// if the haptic impulse was successfully sent to the device even if frequency is ignored or not supported by the device. ///
/// Frequency is currently only functional when the OpenXR Plugin (com.unity.xr.openxr) package is installed /// and the input action is using an input binding to a Haptic Control. ///
public bool SendHapticImpulse(float amplitude, float duration, float frequency) { if (!isActiveAndEnabled) return false; return m_HapticOutput.GetChannelGroup()?.GetChannel()?.SendHapticImpulse(amplitude * m_AmplitudeMultiplier, duration, frequency) ?? false; } internal static HapticImpulsePlayer GetOrCreateInHierarchy(GameObject gameObject) { var hapticImpulsePlayer = gameObject.GetComponentInParent(true); if (hapticImpulsePlayer == null) { // Try to add the component in the hierarchy where it can be found and shared by other interactors. // Otherwise, just add it to this GameObject. var impulseProvider = gameObject.GetComponentInParent(true); var impulseProviderComponent = impulseProvider as Component; hapticImpulsePlayer = impulseProviderComponent != null ? impulseProviderComponent.gameObject.AddComponent() : gameObject.AddComponent(); } return hapticImpulsePlayer; } } }