Search Unity

XR Interaction Toolkit - Set interactable to unselectable by other interactors while selected

Discussion in 'XR Interaction Toolkit and Input' started by flipwon, Jun 18, 2020.

  1. flipwon

    flipwon

    Joined:
    Dec 29, 2016
    Posts:
    179
    Hey guys a quick question,

    Is there a simple way to make an object unable to be selected by other interactors while already selected by another?

    EX: interactable is in left hand, right hand should not be able to select it

    I can't seem to find a quick and painless way to accomplish this, so I'm sure I'm overlooking something.
     
  2. nalex66

    nalex66

    Joined:
    Aug 26, 2022
    Posts:
    54
    Did you ever find a solution to this? Currently facing the same problem.
     
  3. RogueStargun

    RogueStargun

    Joined:
    Aug 5, 2018
    Posts:
    296
    Old way to do this was by overriding IsSelectableBy

    Code (CSharp):
    1. using UnityEngine.XR.Interaction.Toolkit;
    2. namespace DoGames.XR
    3. {
    4.     public class OneHandedGrabInteractable : XRGrabInteractable
    5.     {
    6.         public bool IsSelectableBy(XRSocketInteractor interactor)
    7.         {
    8.             return base.IsSelectableBy((XRBaseInteractor)interactor);
    9.         }
    10.         public override bool IsSelectableBy(XRBaseInteractor interactor)
    11.         {
    12.             // Prevent object from being selected if it's already selected by something that isn't an XRSocketInteractor.
    13.             bool isAlreadyGrabbed = selectingInteractor && (!(selectingInteractor is XRSocketInteractor) && !interactor.Equals(selectingInteractor));
    14.             return base.IsSelectableBy(interactor) && !isAlreadyGrabbed;
    15.         }
    16.     }
    17. }
    No idea what it is now
     
  4. VRDave_Unity

    VRDave_Unity

    Unity Technologies

    Joined:
    Nov 19, 2021
    Posts:
    275
    Hey @nalex66 and @RogueStargun,
    There is a property on the
    XRBaseInteractable
    class called selectMode which lets you toggle between single and multiple. Setting this to single will only allow selection by a single interactor at a time. I think this might solve your problem.
     
  5. Project-NSX

    Project-NSX

    Joined:
    Apr 11, 2019
    Posts:
    25
    Can you please confirm if that is indeed the intended functionality of Select Mode: Single? I've had this issue with XRI since 2020 and every time I have attempted a solution I've been unsuccessful. I have updated the project to the most recent version of XRI and selection mode: single does not prevent other interactions from hovering or selecting an object.
     
  6. nalex66

    nalex66

    Joined:
    Aug 26, 2022
    Posts:
    54
    I found that Select Mode Single did not prevent my hand from targeting an object held by the other hand. My hands would "fight" over the object (rapid transfer from one hand to the other and back). I ended up writing a custom extension of GrabInteractable that doesn't allow selection of an already-held object, based on a Brackey's tutorial. The code is quite simple:

    Code (CSharp):
    1. using UnityEngine.XR.Interaction.Toolkit;
    2.  
    3. public class CustomGrabInteractable : XRGrabInteractable
    4. {
    5.     // Use this instead of XR Grab Interactable to prevent hands fighting over objects.
    6.     // Fighting hands can cause hand animations to break, and causes rapid-fire grab sounds.
    7.     public override bool IsSelectableBy(IXRSelectInteractor interactor)
    8.     {
    9.         bool isAlreadyGrabbed = false;
    10.        
    11.         if (isSelected && !interactor.Equals(firstInteractorSelecting))
    12.         {
    13.             var grabber = firstInteractorSelecting as XRDirectInteractor;
    14.             if (grabber != null)
    15.             {
    16.                 // the grabber is a direct interactor
    17.                 isAlreadyGrabbed = true;
    18.             }
    19.         }
    20.                
    21.         return base.IsSelectableBy(interactor) && !isAlreadyGrabbed;
    22.     }
    23. }
     
    ericprovencher likes this.