Search Unity

Question How to access what gameobject is inside an XR Socket Interactor?

Discussion in 'XR Interaction Toolkit and Input' started by laptsirhc, May 21, 2020.

  1. laptsirhc

    laptsirhc

    Joined:
    Jan 27, 2018
    Posts:
    4
    Hi all,

    I'm basically trying to make a coffee shop game in VR (on HTC Vive). Right now, the coffee machine has a lever that, when you pull it, should have the machine pour out coffee in two streams, one for hot coffee and one for cold coffee. I want the machine to detect, when the lever is pulled, which slots have cups set inside them and only activate the streams above those slots.

    Right now, to place a cup inside the machine (picture a soda fountain), you just put it close enough to the spot and a socket interactor snaps it into place.

    My issue is that I don't know how to figure out which object is currently in the socket. I've looked through the XR Socket Interactor script, but it's a little hard for me to read, as I'm not very experienced. I need to know if a cup is in the socket or not. I have all the cups tagged as "Cup". Any help is greatly appreciated!

    Thanks!
     
  2. DejaMooGames

    DejaMooGames

    Joined:
    Apr 1, 2019
    Posts:
    108
    Check out the documentation for XRBaseInteractor. XRSocketInteractor inherits from it and the functionality you need is located there along with a lot of other useful things. You could access this information by checking if the your cup gameobject is in the XRSocketInteractor.selectTarget property. Another implementation would be to subscribe to the OnSelectEnter and OnSelectExit XRInteractorEvents, you would be able to see which Interactables entered or exited the sockets.
     
    basdere likes this.
  3. ttttkk

    ttttkk

    Joined:
    Oct 2, 2016
    Posts:
    7
    Did you find what you were looking for? I want to do the same thing.
     
  4. SecretNerd

    SecretNerd

    Joined:
    May 18, 2016
    Posts:
    1
    XRSocketInteractor.selectTarget from DejaMooo's answer is now depreciated (Very late 2021). Use
    GetOldestInteractableSelected() method as shown. Hope this helps anyone else, took me too long to work it out.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Interaction.Toolkit;
    5. public class SocketChecking : MonoBehaviour
    6. {
    7.    
    8.     XRSocketInteractor socket;
    9.    
    10.     void Start()
    11.     {
    12.         socket = GetComponent<XRSocketInteractor>();
    13.     }
    14.  
    15.     public void socketCheck()
    16.     {
    17.        
    18.         IXRSelectInteractable objName = socket.GetOldestInteractableSelected();
    19.        
    20.         Debug.Log(objName.transform.name + " in socket of " + transform.name);
    21.     }
     
    VRandStuff, Keep-Frame, Ony and 3 others like this.
  5. MortenVIA

    MortenVIA

    Joined:
    Nov 3, 2021
    Posts:
    1
    You just saved me have been searching for this for weeks !
     
    SecretNerd likes this.
  6. Hacktivist2007

    Hacktivist2007

    Joined:
    Dec 29, 2021
    Posts:
    25
    How do you delete the object in the zone using this method?
     
    Last edited: Apr 15, 2022
  7. IanCole

    IanCole

    Joined:
    Feb 21, 2017
    Posts:
    3
    For anyone attempting to use this kind of thing to check if a socket is simply occupied and you don’t care about what object is actually selected, you can just check the bool XRSocketInteractor.hasSelection instead.

    Bear in mind if you're using XRGrabInteractable with sockets for a drag and drop game, like I am, there's a delay of at least a frame before the bool is updated. Using a simple coroutine with a WaitForEndOfFrame sorted this out in my case. Personally, I opted to override the Drop method of the XRGrabInteractable object, so that I could almost instantly check if the referenced XRSocketInteractor was occupied or not.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.XR.Interaction.Toolkit;
    4.  
    5. public class XRGrabInteractable_Custom : XRGrabInteractable {
    6.  
    7.     [SerializeField, Tooltip("The XRSocketInteractor to be checked.")]
    8.     private XRSocketInteractor xrSocketInteractor;
    9.  
    10.     protected override void Drop() {
    11.         base.Drop();
    12.         StartCoroutine(CheckSocket());
    13.     }
    14.  
    15.     IEnumerator CheckSocket() {
    16.         yield return new WaitForEndOfFrame();
    17.         Debug.Log(xrSocketInteractor.hasSelection);
    18.     }
    19.  
    20. }
     
    Last edited: Jun 13, 2022
    hellobody likes this.
  8. lozkrem

    lozkrem

    Joined:
    May 30, 2022
    Posts:
    1
    This method gets the Interactor but it doesn't seem to get the actual GameObject. Has anyone found a way to get an actual GameObject reference?
     
    UnityEJC likes this.
  9. Bisentoseven

    Bisentoseven

    Joined:
    Jan 6, 2019
    Posts:
    4
    @SecretNerd
    What is your script attached to? The Socket itself?
     
  10. arkantose

    arkantose

    Joined:
    Dec 22, 2021
    Posts:
    8
    Hey Im not sure if you ever got your answer but this is how you would reference it as a game object.

    IXRSelectInteractable screw = socket.GetOldestInteractableSelected();
    GameObject screwCol = screw.transform.gameObject;

    You have to access it through its transform extension :)

    Hope that helps!