Prevent XR Socket Interactors from invoking an Interactable's Select Event

Hi there, I’ve been dabbling with the XR system and noticed that an object that is placed in an XR socket will fire the actions from Select and Deselect on an object.

An example would be if a flashlight is supposed to turn a light on only when held, the light will also be on when in a socket. Is there a way to make it so the Interactable fires its events when selected by an XR Direct Interactor, but NOT when selected by an XR Socket Interactor, but still let the socket hold the Interactable?

The order that the events fire in also seems to be that it will run the deselect event (leaving the socket) immediately after the select event (entering the direct interactor) if you use a direct interactor to remove the object from a socket. In the flashlight example this results in the flashlight being off when heldif you removed it from the socket.

Any help or guidance is appreciated! I suspect that the filters might help with this but I don’t really know how to use them!

Hi,
I don’t think that you can filter the select entered/exited events to be raised only by a certain type of GameObject - you can filter the selecting objects, but an object that will be selected by a socket will trigger the event I believe.

What you could do is simply filter the event inside a Flashlight class that would be connected to its grabbable component. (I assume you are making the flashlight interactable by using the XRGrabInteractable script)
An example of how you could do it :

public class Flashlight
{
    private XRGrabInteractable _grabInteractable;
    void Awake()
    {
        // Retrieve the XRGrabInteractable component and listen to the event
        _grabInteractable = GetComponent<XRGrabInteractable>();
        _grabInteractable.selectEntered.AddListener(GrabInteractable_SelectEntered);
    }
    void OnDestroy()
    {
        // Remove the listening of the event when GameObject is destroyed
        if (_grabInteractable)
            _grabInteractable.selectEntered.RemoveListener(GrabInteractable_SelectEntered);
    }

    private void GrabInteractable_SelectEntered(SelectEnterEventArgs args)
    {
        // Filter the interactor object here
        if (args.interactorObject is XRDirectInteractor)
        {
            SwitchLight();
        }
    }

    private void SwitchLight() { // Code for flashlight light turn on/off }
}

Please note that I haven’t tested this code so you might need to adapt/re-write some things here - this serves as a pseudo-code example.
Hope it helps, otherwise please give more detail about your problem :slight_smile:

1 Like

Hey Reaktion!

Adding listeners and filtering it myself seems like a promising avenue! I’ll take this as a starting point and see how it goes!

1 Like

Hey again, Reaktion!

Just replying again to confirm that this worked for what I needed. I think I’ll have a lot easier of a time following this approach, so thank you for directing me towards it!

1 Like