Haptic feedback for UI?

Hey everyone, I have a simple question that I couldn’t find an answer to it.

I have a 3D menu in my VR game, and I want to be able to send an haptic event whenever I hover on any UI button. BUT, with the Haptic Events and Audio Events and not from script. Like that:

I want to use that way because it will be more easy to detect which hand hovered a UI element instead of just sending haptic to both hands when hovering UI, or try figuring out which hand hovered the UI.

I honestly didn’t manage to achieve my goal. It sounds the simplest thing on earth but it doesn’t work.
Can someone give me a hand here?
I tried to tick the “On Hover Entered” checkbox and nothing happened.

The buttons and all the UI works great but only those events are not working for me.

1 Like

The problem you are having is that the “On Hover Entered” checkbox only works for XRRayInteractors, not for UI buttons. To get haptic feedback when hovering a UI button, you need to use a script.

Here is a simple script that you can use:

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class ButtonHaptics : MonoBehaviour
{
public XRController controller;
public float amplitude = 0.7f;
public float duration = 2f;

void OnHoverEnter(XRBaseInteractor interactor)
{
if (interactor.Controller == controller)
{
controller.SendHapticImpulse(0u, amplitude, duration);
}
}
}

This script will send a haptic impulse to the controller when the button is hovered. You will need to attach this script to the UI button that you want to give haptic feedback to.

Here are the steps on how to set up the script:

  • Create a new script and paste the code above.
  • Attach the script to the UI button that you want to give haptic feedback to.
  • In the Inspector, set the controller property to the XRController that you want to use.
  • Set the amplitude and duration properties to the desired values.

Once you have set up the script, you should be able to get haptic feedback when you hover the UI button.

I hope this helps!

1 Like

We don’t fire hover and select events for UGUI because those go through a fully different event system. We do have the interactor affordance provider that supports affordance events on the interactor side when interacting with UGUI as well, you can try and send haptic pulse events via state callbacks there if take the time to configure it.

This is something we intend to resolve, but out of the box, it’s just not something that works right now.

2 Likes

Thanks for the replies, I ended up using event trigger and OnPointerEnter & OnPointerExit to detect hovering, and “GetInteractor” to detect which controller is it. Thanks.

1 Like

Hey! Maybe you could share the script you wrote for this functionality? That would really help me!

Sure thing.

So for every button you need to add 2 components:
1 - The script I wrote:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.UI;

public class UIbutton : MonoBehaviour
{

    private XRUIInputModule InputModule => EventSystem.current.currentInputModule as XRUIInputModule;
 

    public void OnPointerEnter(PointerEventData eventData)
    {

        XRRayInteractor interactor = InputModule.GetInteractor(eventData.pointerId) as XRRayInteractor;

        if (!interactor) { return; }

        interactor.xrController.SendHapticImpulse(.5f, .5f);

    }

    public void OnPointerExit(PointerEventData eventData)
    {

        XRRayInteractor interactor = InputModule.GetInteractor(eventData.pointerId) as XRRayInteractor;

        if (!interactor) { return; }

        interactor.xrController.SendHapticImpulse(.5f, .5f);

    }

}

(I deleted unnecessary lines to simplify)
Basically, every button will call “OnPointerEnter” when you hover it with the VR controller, and it checks which controller actually hovered it (That was the hard part), and then simply sending haptic impulse to that specific controller.

2 -
You’ll want to add “Event Trigger” component to every button as well. Just press “Add Component” and search for “Event Trigger”.

You can add some more logic inside OnPointerEnter, such as increaing the size of the button when hovering (And decreasing inside “OnPointerExit”) etc…

Hope it helps!

2 Likes

Thanks a lot! I was having trouble getting XR interactor from PointerEventData, but it seems that it is a lot easier than I thought.

1 Like

How did you get OnPointerEnter to be called automatically? No matter what I do I can’t get it to trigger in my scene. Ive changed every setting on the XR Ray Interactor and nothing works. I can interact with the UI with the ray as normal, it even changes the buttons colour on hover and select etc.

Is there anything special to the setup to get the events to be called? Thanks.

EDIT:
I got it working by adding the IPointerEnterHandler and IPointerExitHandler interfaces to the script, this allows the events to be correctly passed through.

1 Like