Why there is no "Hover to Select" option for the XR Interaction Toolkit?

Hi everyone, me and my team are working on a VR project using the XR Interaction Toolkit 3.0.x.

We are developing a simple application with simple interactions that involve grabbing an object, moving it somewhere else to attach it, repeat.

Also, we want to reduce this interaction to the simple touch of the things we want the player to interact with: touch a pen to grab it, touch a drawer to open it, etc.

That said, we expected (and actually, we deeply wanted to) to use the XR Interaction toolkit at its full power, but we found out that, especially for grabbing, the “Touch to interact” solution isn’t replicable.

Since we saw that it is possibile to use Hover to Activate, we were wondering: “Why not selecting on hover also?”

Right now, we are implementing out own custom interaction system based upon the premises, but it feels like a waste to have an already massive functioning interaction system and not being able to use it.

With this thread, I am asking wether or not there is an explanation about the missing of a functionality like this and wether or not could it be implemented in the near future.

This seems possible, but you would definitely want an easy way to deselect the object. So one thing you could do is configure the Near-Far Interactor (or Direct Interactor) by first setting the Select Action Trigger to State and then change the Select input to manual and make sure it is always selected and the select value is 1, as shown in these images:

And then for release of Select, you would want to create a Select Filter. I would imagine you would want it to release when it contacted a specific volume or collider where you want the object to be placed. Here is the documentation on how to create a Select Filter. You can also use the XRPokeFilter as an example of what a complete interaction filter would look like.

1 Like

Hi Dave, this is gold, really.

I appreciate your answer, I totally missed the “input to manual” option.
Can’t wait to use it more deeply.

Thanks!

I stumbled upon this thread just now. The proposed solution didn’t fully work for me, but it certainly got me on the right track, so thanks!

For context: My app uses both XRDirectInteractor as well as XRRayInteractor. I had setup all Interactables to react OnLastSelectExited. For a hover to select feature I initially switched my interactables to use OnLastHoverExited. That does work, but is inconvenient, because now my interactables not only select on direct interaction hovers, but also ray interatcion hovers.

My solution: derive a custom class from XRDirectInteractor. It essentially delivers the same feature that was mentioned by @VRDave_Unity, but may come in handy for even more customized implementations. Here is the boilerplate:

public class XRDirectInteractorHoverToSelect : XRDirectInteractor
{
    protected override void Awake()
    {
        base.Awake();
        selectInput = null;
    }

    protected override void OnHoverEntered(HoverEnterEventArgs args)
    {
        base.OnHoverEntered(args);
        if (Object.ReferenceEquals(args.interactorObject, this))
        {
            IXRSelectInteractable selectInteractable = args.interactableObject as IXRSelectInteractable;
            if (selectInteractable == null || isSelectActive)
                return;
            StartManualInteraction(selectInteractable);
        }
    }

    protected override void OnHoverExited(HoverExitEventArgs args)
    {
        base.OnHoverExited(args);
        if (Object.ReferenceEquals(args.interactorObject, this))
        {
            IXRSelectInteractable selectInteractable = args.interactableObject as IXRSelectInteractable;
            if (selectInteractable == null || !IsSelecting(selectInteractable))
                return;
            EndManualInteraction();
        }
    }
}

So essentially StartManualInteraction and EndManualInteraction are key. Setting selectInput = null is necessary to make sure we in fact have full control over select start and end from inside this script.

I would encourage anyone not to be afraid of deriving from any XRInteractor / XRInteractable. I’ve done it a ton of times for various purposes and it has always been fairly straight forward and led to pretty clean logic. Have been a big fan of XRIT for many years!